package com.rytx.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.alipay.v3.ApiClient;
import com.alipay.v3.Configuration;
import com.alipay.v3.util.GenericExecuteApi;
import com.alipay.v3.util.model.AlipayConfig;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.github.pagehelper.util.StringUtil;
import com.rytx.common.config.AliyunSmsConfig;
import com.rytx.common.config.MyAliPayConfig;
import com.rytx.common.core.domain.AjaxResult;
import com.rytx.common.core.domain.model.ArtUser;
import com.rytx.common.utils.AmountUtils;
import com.rytx.common.utils.DateUtils;
import com.rytx.common.utils.StringUtils;
import com.rytx.common.utils.uuid.MyIncrementGenerator;
import com.rytx.system.domain.ArtOrderAfter;
import com.rytx.system.domain.ShippingAddresses;
import com.rytx.system.domain.vo.CartArtOrder;
import com.rytx.system.domain.ysp.*;
import com.rytx.system.mapper.*;
import com.rytx.system.service.IAliConfigService;
import com.rytx.system.service.IArtAfterLogService;
import com.rytx.system.service.IArtOrderService;
import com.rytx.system.wxpay.MyWXPayConfig;
import com.rytx.system.wxpay.WXPay;
import com.rytx.system.wxpay.WXPayUtil;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 艺术订单信息Service业务层处理
 *
 * @author rytx
 * @date 2024-05-12
 */
@Service
public class ArtOrderServiceImpl implements IArtOrderService
{
    private static final org.slf4j.Logger log = LoggerFactory.getLogger(ArtOrderServiceImpl.class);
    private static final String ORDER_PREFIX = "ZMMY";
    private static final String REQ_ORDER_PREFIX = "REQZMMY";

    @Autowired
    private AliyunSmsConfig aliyunSmsConfig;

    @Autowired
    private MyWXPayConfig wxPayConfig;
    @Autowired
    private ArtOrderMapper artOrderMapper;
    @Autowired
    private MyAliPayConfig myAliPayConfig;
    @Autowired
    private ArtRentalMapper artRentalMapper;
    @Autowired
    private IAliConfigService aliConfigService;

    @Autowired
    private ArtOperationDetailsMapper artOperationDetailsMapper;

    @Autowired
    private ArtUserMapper artUserMapper;

    @Autowired
    private ArtOrderAfterMapper artOrderAfterMapper;

    @Autowired
    private ShippingAddressesMapper shippingAddressesMapper;

    @Autowired
    private ArtFundingDetailsMapper artFundingDetailsMapper;

    @Autowired
    private ArtMessageMapper artMessageMapper;

    @Autowired
    private ArtDiscountCycleMapper artDiscountCycleMapper;

    @Autowired
    private ArtServiceChargeMapper artServiceChargeMapper;

    @Override
    public int updateByOrderNo(ArtOrder artOrder) {
        return artOrderMapper.updateByOrderNo(artOrder);
    }

    @Override
    public void takComplete(String orderNo) {
        artOrderMapper.takComplete(orderNo);
    }

    @Override
    public List<ArtOrder> appRecoveryList(ArtOrder artOrder) {
        return artOrderMapper.selectArtOrderSortById(artOrder);
    }

    @Override
    public AjaxResult manualProcessing(ArtOrder order) {
        String msg = "";
        // 1、查询订单完整数据
        ArtOrder artOrder = artOrderMapper.getOrderByOrderNo(order.getOrderNo());
        artOrder.setRefundAmount(order.getRefundAmount());
        artOrder.setUnfreezeAmount(order.getUnfreezeAmount());

        ArtOrder param = new ArtOrder();
        param.setOrderNo(order.getOrderNo());

        // 2、退款，refundAmount
        if(order.getRefundAmount().compareTo(BigDecimal.ZERO) > 0) {
            boolean refundStatus = zmnRefund(artOrder);
            if (refundStatus) {
                boolean unfreezeStatus = zmnRefundStatus(artOrder);
                if (unfreezeStatus) {
                    msg += "退款成功，金额：" + artOrder.getRefundAmount() + "；/r/n";
                    log.info("订单{}退款成功，金额：{}", artOrder.getOrderNo(), artOrder.getRefundAmount());
                    addArtFundingDetails(artOrder, "2", artOrder.getRefundAmount().toString(), artOrder.getArtName() + ":租赁订单退款");
                    param.setOrderStatus("8");
                    artOrderMapper.updateByOrderNo(param);
                }else{
                    msg += "退款失败，金额：" + artOrder.getRefundAmount() + "；/r/n";
                    artOrder.setOrderStatus("7"); // 退款失败，状态回到 7-退款处理中
                    artOrderMapper.updateByOrderNo(param);
                }
            }
        }
        // 3、解冻，unfreezeAmount
        if(order.getUnfreezeAmount().compareTo(BigDecimal.ZERO) > 0) {
            boolean zmnfreeze = zmnfreeze(artOrder);
            if(zmnfreeze){
                msg += "解冻成功，金额：" + artOrder.getUnfreezeAmount() + "；/r/n";
            }
            log.info("订单{}解冻{}, 金额：{}", artOrder.getOrderNo(), zmnfreeze ? "成功" : "失败", order.getUnfreezeAmount());
        }

        // 4、解冻剩余金额，restAmount
        if("1".equals(order.getRestAmount())) {
            AjaxResult ajaxResult = completeZmOrder(artOrder); // 完结订单
            if (ajaxResult.isError()) {
                msg += "订单完结失败；/r/n";
                log.error("订单{}完结失败", artOrder.getOrderNo());
            }else {
                msg += "订单完结成功；/r/n";
                log.info("订单{}完结成功", artOrder.getOrderNo());
            }
        }

        return AjaxResult.success(msg);
    }

    @Override
    public List<ArtOrder> deliveryList(ArtOrder artOrder) {
        return artOrderMapper.deliveryList(artOrder);
    }

    @Override
    public List<ArtOrder> recoveryList(ArtOrder artOrder) {
        return artOrderMapper.recoveryList(artOrder);
    }

    @Override
    public String createLeaseBuyOrder(ArtOrder order) {
        // 设置请求参数
        String nowSrt = DateUtils.dateTimeNow();
        String orderNo = ORDER_PREFIX + nowSrt;
        String outTradeNo = "ZFBBUY" + nowSrt;

        order.setOrderName(DateUtils.getDate());
        order.setAliTradeNo(outTradeNo);

        Calendar calendar = Calendar.getInstance();
        Date currentDate = calendar.getTime();

        // 租赁订单
        if(order.getCartRentalIds() != null && !"".equals(order.getCartRentalIds())){
            List<ArtRental> artRentals = artRentalMapper.getArtRentalByIds(order.getCartRentalIds());
            BigDecimal totalAmount = new BigDecimal(0);
            for(ArtRental artRentalItem : artRentals){
                totalAmount = totalAmount.add(artRentalItem.getPrice());
            }
            order.setFreezeAmount(totalAmount); // 冻结金额，押金，等于商品价格
        }

        order.setRentalStatus("0"); //租赁状态 0-待确认 1-租赁中 2-已归还 3-已取消 4-已延期



        order.setOrderNo(orderNo);
        order.setOrderRequestNo(orderNo);

        order.setOrderStatus("0");//待确认
        order.setCreateTime(currentDate);
        order.setUpdateTime(currentDate);

        // 组装收货数据
        if(order.getUserAddressId() != null){
            ShippingAddresses shippingAddresses = shippingAddressesMapper.selectShippingAddressesById(order.getUserAddressId());
            String deliveryAddress = shippingAddresses.getStreetAddress() + shippingAddresses.getDistrict();
            order.setDeliveryAddress(deliveryAddress);
            order.setDeliveryName(shippingAddresses.getRecipientName());
            order.setDeliveryPhone(shippingAddresses.getPhoneNumber());
        }

        // 创建支付宝支付订单
        String result = createAlipayOrder(order);

        if(result != null && !"".equals(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result).getJSONObject("alipay_trade_create_response");

            if(jsonObject.getString("code").equals("10000")) {
                artOrderMapper.insertArtOrder(order);
                return jsonObject.getString("trade_no");
            }
        }

        return "订单创建失败";
    }

    /**
     * 单个订单
     * 已过7天无理由但未满1个月退还，租金还未扣除的情况下，需缴纳服务费（一个月租金）
     * @param artServiceCharge
     */
    @Override
    public void serviceChargeUtil(ArtServiceCharge artServiceCharge){
        ArtOrder artOrder = artOrderMapper.getOrderByOrderNo(artServiceCharge.getOrderNo());
        String deductionCycle = "1"; // 扣款周期，单位：月

        ArtDiscountCycle artDiscountCycle = new ArtDiscountCycle();
        artDiscountCycle.setLeaseCycle(deductionCycle);
        artDiscountCycle = artDiscountCycleMapper.getDiscountCycleByParam(artDiscountCycle); // 根据扣款周期，查询扣款比例
        BigDecimal deductionPercentage = new BigDecimal(artDiscountCycle.getLeaseDiscount());

        // 2.1、计算首期是多少天，是从签收日开始到当月月底是多少天
        Date startDate = artOrder.getSignDate(); // 签收日期
        // 使用 Calendar 处理 Date
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);


        Calendar nextMonthEnd = (Calendar) calendar.clone();

        /*
        // 获取下个月的最后一天
        // 将月份加1
        nextMonthEnd.add(Calendar.MONTH, 1);
        // 设置日期为下个月的第一天
        nextMonthEnd.set(Calendar.DAY_OF_MONTH, 1);
        // 将日期退回到上一个日期的最后一天
        nextMonthEnd.add(Calendar.DAY_OF_MONTH, -1);
        */

        // 获取当月的最后一天
        // 设置日期为下个月的第一天
        nextMonthEnd.set(Calendar.DAY_OF_MONTH, 1);
        // 将月份加1
        nextMonthEnd.add(Calendar.MONTH, 1);
        // 将日期退回到上一个日期的最后一天
        nextMonthEnd.add(Calendar.DAY_OF_MONTH, -1);

        Date endDate = nextMonthEnd.getTime(); // 租赁结束日期

        // 计算天数差
        Long diffInMillis = nextMonthEnd.getTimeInMillis() - calendar.getTimeInMillis();
        Long diffInDays = diffInMillis / (24 * 60 * 60 * 1000); // 转换为天数
        diffInDays += 1; // 需要加上开始日期那一天，所以加1

        // 2.2、查询订单商品的一天租金的总和
        // 根据当前时间是否在折扣活动时间或者特价活动时间内查询，如果在折扣活动时间区折扣，如果在特价活动时间取特价，都没有的话使用普通租金
        BigDecimal totalRentalFee = new BigDecimal(0);
        for(String cartRentalId : artOrder.getCartRentalIds().split(",")){
            ArtRental artRental = artRentalMapper.getTotalRentalFeeByIds(cartRentalId);
            if(artRental.getActivityDiscountPrice() > 0){ // 存在活动折扣
                totalRentalFee = totalRentalFee.add(artRental.getRentalFee().multiply(new BigDecimal(artRental.getActivityDiscountPrice())).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
            }else if(!"0.00".equals(artRental.getActivitySpecialPrice())){ // 存在特价
                totalRentalFee = totalRentalFee.add(new BigDecimal(artRental.getActivitySpecialPrice()));
            }else{
                totalRentalFee = totalRentalFee.add(artRental.getRentalFee());
            }
        }

        // 2.3、计算首期租金，就是totalRentalFee*diffInDays
        BigDecimal firstRentalFee = totalRentalFee.multiply(new BigDecimal(diffInDays.toString()));

        // 首期租金要乘以扣款比例
        firstRentalFee = firstRentalFee.multiply(deductionPercentage).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);

        artOrder.setOrderAmount(firstRentalFee); // 订单金额等于首期租金
        artOrder.setRentalStartDate(startDate); // 租赁开始日期
        artOrder.setRentalEndDate(endDate); // 租赁结束日期
        artOrder.setRentalDays(diffInDays.intValue()); // 租赁天数
        artOrder.setUpdateTime(new Date()); // 更新时间

        // 2.4、更新订单表，设置首期租金并扣款
        // 2.4.1、如果是普通支付的租赁订单，直接把order_amount修改成扣款金额不用扣款，AliTradeNo是支付宝普通支付的交易号
        if(artOrder.getAliTradeNo() != null){
            artOrderMapper.updateByOrderNo(artOrder);
        }else{
            // 2.4.2、如果是支付宝预授权的租赁订单，需要调用支付宝芝麻信用接口扣款，扣款成功后才可以修改order_amount
            boolean zmChargebacksFlag =  zmChargebacks(artOrder); // 冻结资金部分扣款
            if(zmChargebacksFlag){ // 扣款成功
                artOrderMapper.updateByOrderNo(artOrder);
            }else { // 扣款失败
                log.error("订单{}首期租金扣款失败", artOrder.getOrderNo());
                artOrder.setOrderStatus("88"); // 订单状态 88-需要手动支付
                artOrder.setRecoveryStatus("1"); // 1-追缴未支付
                artOrder.setAliTradeNo(artOrder.getOrderNo()); // 设置创建支付宝订单的交易号
                artOrder.setRecoveryReason("该订单首期租金扣除失败，请及时支付"); // 追缴原因
                artOrderMapper.updateByOrderNo(artOrder);
            }
        }

        // 2.5、更新服务费表，设置扣款状态
        artServiceCharge.setStatus("1"); // 扣款状态 1-已扣款
        artServiceCharge.setUpdateTime(new Date()); // 更新时间
        artServiceChargeMapper.update(artServiceCharge);
    }

    /**
     * 已过7天无理由但未满1个月退还，租金还未扣除的情况下，需缴纳服务费（一个月租金）
     */
    @Override
    public void serviceChargeTask(){
        // 1、查询ArtServiceCharge表中status=0的记录，即未扣款的服务费
        List<ArtServiceCharge> artServiceCharges = artServiceChargeMapper.selectAllByStatus("0");

        // 2、遍历artServiceCharges，查询对应的订单，按首期扣款操作，扣款周期为1个月
        for(ArtServiceCharge artServiceCharge : artServiceCharges){
            ArtOrder artOrder = artOrderMapper.getOrderByOrderNo(artServiceCharge.getOrderNo());
            String deductionCycle = "1"; // 扣款周期，单位：月

            ArtDiscountCycle artDiscountCycle = new ArtDiscountCycle();
            artDiscountCycle.setLeaseCycle(deductionCycle);
            artDiscountCycle = artDiscountCycleMapper.getDiscountCycleByParam(artDiscountCycle); // 根据扣款周期，查询扣款比例
            BigDecimal deductionPercentage = new BigDecimal(artDiscountCycle.getLeaseDiscount());

            // 2.1、计算首期是多少天，是从签收日开始到当月月底是多少天
            Date startDate = artOrder.getSignDate(); // 签收日期
            // 使用 Calendar 处理 Date
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);

            // 获取下个月的最后一天
            Calendar nextMonthEnd = Calendar.getInstance();
            nextMonthEnd.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + Integer.parseInt(deductionCycle), 1);
            nextMonthEnd.add(Calendar.DAY_OF_MONTH, -1); // 设置为下个月的最后一天

            Date endDate = nextMonthEnd.getTime(); // 租赁结束日期

            // 计算天数差
            Long diffInMillis = nextMonthEnd.getTimeInMillis() - calendar.getTimeInMillis();
            Long diffInDays = diffInMillis / (24 * 60 * 60 * 1000); // 转换为天数
            diffInDays += 1; // 需要加上开始日期那一天，所以加1

            // 2.2、查询订单商品的一天租金的总和
            // 根据当前时间是否在折扣活动时间或者特价活动时间内查询，如果在折扣活动时间区折扣，如果在特价活动时间取特价，都没有的话使用普通租金
            BigDecimal totalRentalFee = new BigDecimal(0);
            for(String cartRentalId : artOrder.getCartRentalIds().split(",")){
                ArtRental artRental = artRentalMapper.getTotalRentalFeeByIds(cartRentalId);
                if(artRental.getActivityDiscountPrice() > 0){ // 存在活动折扣
                    totalRentalFee = totalRentalFee.add(artRental.getRentalFee().multiply(new BigDecimal(artRental.getActivityDiscountPrice())).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
                }else if(!"0.00".equals(artRental.getActivitySpecialPrice())){ // 存在特价
                    totalRentalFee = totalRentalFee.add(new BigDecimal(artRental.getActivitySpecialPrice()));
                }else{
                    totalRentalFee = totalRentalFee.add(artRental.getRentalFee());
                }
            }

            // 2.3、计算首期租金，就是totalRentalFee*diffInDays
            BigDecimal firstRentalFee = totalRentalFee.multiply(new BigDecimal(diffInDays.toString()));

            // 首期租金要乘以扣款比例
            firstRentalFee = firstRentalFee.multiply(deductionPercentage).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);

            artOrder.setOrderAmount(firstRentalFee); // 订单金额等于首期租金
            artOrder.setRentalStartDate(startDate); // 租赁开始日期
            artOrder.setRentalEndDate(endDate); // 租赁结束日期
            artOrder.setRentalDays(diffInDays.intValue()); // 租赁天数
            artOrder.setUpdateTime(new Date()); // 更新时间

            // 2.4、更新订单表，设置首期租金并扣款
            // 2.4.1、如果是普通支付的租赁订单，直接把order_amount修改成扣款金额不用扣款，AliTradeNo是支付宝普通支付的交易号
            if(artOrder.getAliTradeNo() != null){
                artOrderMapper.updateByOrderNo(artOrder);
            }else{
                // 2.4.2、如果是支付宝预授权的租赁订单，需要调用支付宝芝麻信用接口扣款，扣款成功后才可以修改order_amount
                boolean zmChargebacksFlag =  zmChargebacks(artOrder); // 冻结资金部分扣款
                if(zmChargebacksFlag){ // 扣款成功
                    artOrderMapper.updateByOrderNo(artOrder);
                }else { // 扣款失败
                    log.error("订单{}首期租金扣款失败", artOrder.getOrderNo());
                    artOrder.setOrderStatus("88"); // 订单状态 88-需要手动支付
                    artOrder.setRecoveryStatus("1"); // 1-追缴未支付
                    artOrder.setAliTradeNo(artOrder.getOrderNo()); // 设置创建支付宝订单的交易号
                    artOrder.setRecoveryReason("该订单首期租金扣除失败，请及时支付"); // 追缴原因
                    artOrderMapper.updateByOrderNo(artOrder);
                }
            }

            // 2.5、更新服务费表，设置扣款状态
            artServiceCharge.setStatus("1"); // 扣款状态 1-已扣款
            artServiceCharge.setUpdateTime(new Date()); // 更新时间
            artServiceChargeMapper.update(artServiceCharge);
        }
    }

    /**
     * 首期扣款租赁订单
     */
    @Override
    public void firstPaymentTask() {
        // 1、查询需要首期扣款的租赁订单，有签收日期sign_date!=null，并且没有订单金额order_amount=null的，并且afterStatus=0没有售后的，并且recoveryStatus=0没有追缴的
        List<ArtOrder> artOrders = artOrderMapper.getArtOrderFirstPayment(new ArtOrder());

        // 2、遍历订单，计算首期扣款金额（首期时间是从签收日开始到当月月底），扣款，其中如果是普通支付的租赁订单，直接把order_amount修改成扣款金额不用扣款
        for(ArtOrder artOrder : artOrders){
            String deductionCycle = artOrder.getDeductionCycle(); // 扣款周期，单位：月

            ArtDiscountCycle artDiscountCycle = new ArtDiscountCycle();
            artDiscountCycle.setLeaseCycle(deductionCycle);
            artDiscountCycle = artDiscountCycleMapper.getDiscountCycleByParam(artDiscountCycle); // 根据扣款周期，查询扣款比例
            BigDecimal deductionPercentage = new BigDecimal(artDiscountCycle.getLeaseDiscount());

            // 2.1、计算首期是多少天，是从签收日开始到当月月底是多少天
            Date startDate = artOrder.getSignDate(); // 签收日期
            // 使用 Calendar 处理 Date
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);

            // 获取下个月的最后一天
            Calendar nextMonthEnd = Calendar.getInstance();
            nextMonthEnd.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + Integer.parseInt(deductionCycle), 1);
            nextMonthEnd.add(Calendar.DAY_OF_MONTH, -1); // 设置为下个月的最后一天

            Date endDate = nextMonthEnd.getTime(); // 租赁结束日期

            // 计算天数差
            Long diffInMillis = nextMonthEnd.getTimeInMillis() - calendar.getTimeInMillis();
            Long diffInDays = diffInMillis / (24 * 60 * 60 * 1000); // 转换为天数
            diffInDays += 1; // 需要加上开始日期那一天，所以加1

            // 2.2、查询订单商品的一天租金的总和
            // 根据当前时间是否在折扣活动时间或者特价活动时间内查询，如果在折扣活动时间区折扣，如果在特价活动时间取特价，都没有的话使用普通租金
            BigDecimal totalRentalFee = new BigDecimal(0);
            for(String cartRentalId : artOrder.getCartRentalIds().split(",")){
                ArtRental artRental = artRentalMapper.getTotalRentalFeeByIds(cartRentalId);
                if(artRental.getActivityDiscountPrice() > 0){ // 存在活动折扣
                    totalRentalFee = totalRentalFee.add(artRental.getRentalFee().multiply(new BigDecimal(artRental.getActivityDiscountPrice())).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
                }else if(!"0.00".equals(artRental.getActivitySpecialPrice())){ // 存在特价
                    totalRentalFee = totalRentalFee.add(new BigDecimal(artRental.getActivitySpecialPrice()));
                }else{
                    totalRentalFee = totalRentalFee.add(artRental.getRentalFee());
                }
            }

            // 2.3、计算首期租金，就是totalRentalFee*diffInDays
            BigDecimal firstRentalFee = totalRentalFee.multiply(new BigDecimal(diffInDays.toString()));

            // 首期租金要乘以扣款比例
            firstRentalFee = firstRentalFee.multiply(deductionPercentage).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);

            artOrder.setOrderAmount(firstRentalFee); // 订单金额等于首期租金
            artOrder.setRentalStartDate(startDate); // 租赁开始日期
            artOrder.setRentalEndDate(endDate); // 租赁结束日期
            artOrder.setRentalDays(diffInDays.intValue()); // 租赁天数
            artOrder.setUpdateTime(new Date()); // 更新时间

            // 2.4、更新订单表，设置首期租金并扣款
            // 2.4.1、如果是普通支付的租赁订单，直接把order_amount修改成扣款金额不用扣款，AliTradeNo是支付宝普通支付的交易号
            if(artOrder.getAliTradeNo() != null){
                artOrderMapper.updateByOrderNo(artOrder);
            }else{
                // 2.4.2、如果是支付宝预授权的租赁订单，需要调用支付宝芝麻信用接口扣款，扣款成功后才可以修改order_amount
                boolean zmChargebacksFlag =  zmChargebacks(artOrder); // 冻结资金部分扣款
                if(zmChargebacksFlag){ // 扣款成功
                    artOrderMapper.updateByOrderNo(artOrder);
                }else { // 扣款失败
                    log.error("订单{}首期租金扣款失败", artOrder.getOrderNo());
                    artOrder.setOrderStatus("88"); // 订单状态 88-需要手动支付
                    artOrder.setRecoveryStatus("1"); // 1-追缴未支付
                    artOrder.setAliTradeNo(artOrder.getOrderNo()); // 设置创建支付宝订单的交易号
                    artOrder.setRecoveryReason("该订单首期租金扣除失败，请及时支付"); // 追缴原因
                    artOrderMapper.updateByOrderNo(artOrder);
                }
            }
        }
    }

    @Override
    public ArtOrder getOrderByOrderNo(String platOrderNo) {
        return artOrderMapper.getOrderByOrderNo(platOrderNo);
    }

    @Override
    public Long appSelectChildOrderCount(String orderNo) {
        return artOrderMapper.appSelectChildOrderCount(orderNo);
    }

    /**
     * 组装租赁的主订单，是否有子订单，总租期，租赁结束时间
     * @param order
     */
    @Override
    public ArtOrder assemblyLeaseMainOrder(ArtOrder order) {
        if("2".equals(order.getOrderType())){ // 购买订单不做处理
            return order;
        }
        // 是否有子订单
        if(artOrderMapper.appSelectChildOrderCount(order.getOrderNo()) > 0){
            order.setHasChild(true);
        }

        // 总租期
        Integer rentalDays = order.getRentalDays();
        if(rentalDays == null){
            rentalDays = 0;
        }

        // 总租金
        BigDecimal amount = order.getOrderAmount();
        if(amount == null){
            amount = new BigDecimal(0);
        }

        // 组装参数，查询已支付的续租订单
        List<ArtOrder> childOrders = artOrderMapper.getcheckLeaseRenewalZmOrder(order);

        for(ArtOrder childOrder : childOrders){
            if(childOrder.getRentalDays() != null && childOrder.getParentOrderNo() != null){
                rentalDays += childOrder.getRentalDays();
            }

            if(childOrder.getOrderAmount() != null && childOrder.getParentOrderNo() != null){
                amount = amount.add(childOrder.getOrderAmount());
            }
        }

        // 总租期
        order.setRentalDays(rentalDays);

        // 总租金
        order.setOrderAmount(amount);

        // 租赁结束时间
        if(childOrders != null && childOrders.size() > 0 && childOrders.get(0).getRentalEndDate() != null){
            order.setRentalEndDate(childOrders.get(childOrders.size() - 1).getRentalEndDate());
        }

        return order;
    }

    /**
     * 根据运单号和快递公司编号查询订单
     * */
    @Override
    public ArtOrder getOrderByNu(String nu, String com) {
        return artOrderMapper.getOrderByNu(nu, com);
    }

    /**
     * 查询艺术订单信息
     *
     * @param id 艺术订单信息主键
     * @return 艺术订单信息
     */
    @Override
    public ArtOrder selectArtOrderById(Long id)
    {
        return artOrderMapper.selectArtOrderById(id);
    }

    @Override
    public ArtOrder selectArtOrderByParam(ArtOrder artOrder) {
        return artOrderMapper.selectArtOrderByParam(artOrder);
    }

    /**
     * 查询是否存在逾期订单
     *
     * @param artOrder 艺术订单信息
     * @return 预期信息
     */
    @Override
    public List<ArtOrder> selectArtOrderOverdue(ArtOrder artOrder) {
        return artOrderMapper.selectArtOrderOverdue(artOrder);
    }

    @Override
    public String createOrder(ArtOrder order) {
        try{
            AlipayFundAuthOrderAppFreezeRequest request = new AlipayFundAuthOrderAppFreezeRequest();
            // 设置异步通知
            request.setNotifyUrl(myAliPayConfig.getNotifyUrl());
            // 设置请求参数
            String nowSrt = DateUtils.dateTimeNow();
            String orderNo = ORDER_PREFIX + nowSrt;

            order.setOrderName(DateUtils.getDate());

            Calendar calendar = Calendar.getInstance();
            Date currentDate = calendar.getTime();

            // 租赁订单
            if("1".equals(order.getOrderType())) {
                if(order.getCartRentalIds() != null && !"".equals(order.getCartRentalIds())){
                    List<ArtRental> artRentals = artRentalMapper.getArtRentalByIds(order.getCartRentalIds());
                    BigDecimal totalAmount = new BigDecimal(0);
                    for(ArtRental artRentalItem : artRentals){
                        totalAmount = totalAmount.add(artRentalItem.getPrice());
                    }
                    order.setFreezeAmount(totalAmount); // 冻结金额，押金，等于商品价格
                }

                order.setRentalStatus("0"); //租赁状态 0-待确认 1-租赁中 2-已归还 3-已取消 4-已延期
            }

            order.setOrderNo(orderNo);
            order.setOrderRequestNo(orderNo);

            order.setOrderStatus("0");//待确认
            order.setCreateTime(currentDate);
            order.setUpdateTime(currentDate);

            // 组装收货数据
            if(order.getUserAddressId() != null){
                ShippingAddresses shippingAddresses = shippingAddressesMapper.selectShippingAddressesById(order.getUserAddressId());
                String deliveryAddress = shippingAddresses.getStreetAddress() + shippingAddresses.getDistrict();
                order.setDeliveryAddress(deliveryAddress);
                order.setDeliveryName(shippingAddresses.getRecipientName());
                order.setDeliveryPhone(shippingAddresses.getPhoneNumber());
            }

            // 设置业务参数
            JSONObject bizContent = getJsonObject(order);

            // 设置整体请求参数
            request.setBizContent(bizContent.toString());

            log.info("创建免押订单请求参数:{}",bizContent.toString());
            // 使用sdkExecute方法发起请求
            AlipayFundAuthOrderAppFreezeResponse response = aliConfigService.client().sdkExecute(request);
            if(response.isSuccess()){
                log.info("创建免押订单调用成功,返回结果:{}",response.getBody());
                order.setReqMessage(response.getBody());
                order.setReqDate(new Date());
                int i = insertArtOrder(order);

                if(i == 0) {
                    return "创建免押订单失败";
                }

                return response.getBody();
            } else {
                log.error("创建免押订单调用失败,错误信息:{}",response.getSubMsg());
                return "创建免押订单调用失败";
            }
        } catch (Exception e) {
            // 处理支付宝API异常
            log.error("创建免押订单接口调用异常", e);
            return "创建免押订单接口调用异常";
        }
    }

    private static JSONObject getJsonObject(ArtOrder artOrder) {
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_order_no", artOrder.getOrderNo());
        bizContent.put("out_request_no", artOrder.getOrderNo());
        bizContent.put("order_title", artOrder.getOrderName());
        bizContent.put("amount", artOrder.getFreezeAmount().toString());//取值范围：[0.01,100000000.00]
        bizContent.put("product_code","PREAUTH_PAY");//PREAUTH_PAY
        JSONObject extraParam = getJsonObject();
        bizContent.put("extra_param",extraParam);
        return bizContent;
    }

    private static JSONObject getJsonObject() {
        JSONObject extraParam = new JSONObject();
        //extraParam.put("category",myAliPayConfig.getCategory());//授权业务对应的类目：必传，value 为业务分类，例如：充电桩业务传 CHARGE_PILE_CAR 。参考：https://opendocs.alipay.com/open/10719  	ZMSC_1_37_1  ZMSC_1_37_3 RENT_GREEN_PLANT
        extraParam.put("category","RENT_GREEN_PLANT");//[{"categoryCode":"[RENT_GREEN_PLANT]"},{"categoryCode":"[ZMSC_1_37_1]"},{"categoryCode":"[ZMSC_1_37_3]"}]
        extraParam.put("serviceId","2024040400000000000094888100");//信用服务ID：必传。信用服务 ID  需要商家在 开放平台-芝麻免押-信用服务管理 创建信用服务获取。在创建过程中如果有其它疑问，可以咨询芝麻客服小二（0571-88158055 转 2）。
        return extraParam;
    }


    /**
     * 查询艺术订单信息列表
     *
     * @param artOrder 艺术订单信息
     * @return 艺术订单信息
     */
    @Override
    public List<ArtOrder> selectArtOrderList(ArtOrder artOrder)
    {
        return artOrderMapper.selectArtOrderList(artOrder);
    }

    @Override
    public List<ArtOrder> selectArtOrderListByUserId(Long userId) {
        return artOrderMapper.selectArtOrderListByUserId(userId);
    }

    /**
     * 新增艺术订单信息
     *
     * @param artOrder 艺术订单信息
     * @return 结果
     */
    @Override
    public int insertArtOrder(ArtOrder artOrder)
    {
        return artOrderMapper.insertArtOrder(artOrder);
    }

    /**
     * 修改艺术订单信息，根据订单状态修改库存信息
     *
     * @param artOrder 艺术订单信息
     * @return 结果
     */
    @Override
    public int updateArtOrder(ArtOrder artOrder)
    {
        int i = artOrderMapper.updateArtOrder(artOrder);
        if(i > 0) {
            if(artOrder.getOrderStatus().equals("1")){
                // 减库存
                subtractGoodsNum(artOrder);
            }
        }
        return i;
    }

    @Override
    public int updateArtOrderSignDate(ArtOrder update) {
        return artOrderMapper.updateArtOrder(update);
    }

    @Override
    public List<ArtOrder> appSelectArtOrderList(ArtOrder artOrder) {
        return artOrderMapper.appSelectArtOrderList(artOrder);
    }

    /**
     * 批量删除艺术订单信息
     *
     * @param ids 需要删除的艺术订单信息主键
     * @return 结果
     */
    @Override
    public int deleteArtOrderByIds(Long[] ids)
    {
        return artOrderMapper.deleteArtOrderByIds(ids);
    }

    /**
     * 删除艺术订单信息信息
     *
     * @param id 艺术订单信息主键
     * @return 结果
     */
    @Override
    public int deleteArtOrderById(Long id)
    {
        return artOrderMapper.deleteArtOrderById(id);
    }

    @Override
    public ArtOrder orderdetails(Long id) {
        return artOrderMapper.orderdetails(id);
    }

    @Override
    public List<ArtOrder> orderTwoList(ArtOrder artOrder) {
        return artOrderMapper.orderTwoList(artOrder);
    }

    /**
     * 创建支付宝购买订单
     * @param order
     * @return
     */
    @Override
    public String buyOrder(ArtOrder order) {
        String payType = order.getPayType();
        String prefix  = "ZFBBUY";
        if("2".equals(payType)){
            prefix  = "WXBUY";
        }
        // 设置请求参数
        String nowSrt = DateUtils.dateTimeNow();
        String orderNo = prefix+ nowSrt;
        String outTradeNo = prefix + nowSrt;
        ArtRental artRental = artRentalMapper.selectArtRentalById(order.getArtRentalId());

        if(ObjectUtil.isNull(artRental)) {
            return "商品不存在";
        }

        order.setOrderAmount(artRental.getPrice());
        order.setOrderName(DateUtils.getDate());
        order.setArtName(artRental.getArtName());
        Calendar calendar = Calendar.getInstance();
        Date currentDate = calendar.getTime();

        order.setOrderNo(orderNo);
        order.setOrderRequestNo(orderNo);

        if("2".equals(payType)){//微信支付
            //wechatOrder paymentMethod
            order.setWechatOrder(outTradeNo);
            order.setPaymentMethod("wx");
        }else if("1".equals(payType)){//支付宝支付
            order.setAliTradeNo(outTradeNo);
            order.setPaymentMethod("alipay");
        }else{
            throw new RuntimeException("支付方式错误");
        }

        order.setOrderStatus("0");//待确认
        order.setCreateTime(currentDate);
        order.setUpdateTime(currentDate);

        // 组装收货数据
        if(order.getUserAddressId() != null){
            ShippingAddresses shippingAddresses = shippingAddressesMapper.selectShippingAddressesById(order.getUserAddressId());
            String deliveryAddress = shippingAddresses.getStreetAddress() + shippingAddresses.getDistrict();
            order.setDeliveryAddress(deliveryAddress);
            order.setDeliveryName(shippingAddresses.getRecipientName());
            order.setDeliveryPhone(shippingAddresses.getPhoneNumber());
        }

        if("2".equals(payType)){//微信支付
            String wxOrder = createWxOrder(order);
            artOrderMapper.insertArtOrder(order);
            return wxOrder;
        }else if("1".equals(payType)){//支付宝支付
            // 创建支付宝支付订单
            String result = createAlipayOrder(order);

            if(result != null && !"".equals(result)) {
                JSONObject jsonObject = JSONObject.parseObject(result).getJSONObject("alipay_trade_create_response");

                if(jsonObject.getString("code").equals("10000")) {
                    artOrderMapper.insertArtOrder(order);
                    return jsonObject.getString("trade_no");
                }
            }

            return "订单创建失败";
        }else{
            throw new RuntimeException("支付方式错误");
        }

    }


    /**
     * 购物车购买订单
     * */
    @Override
    public String cartByOrder(CartArtOrder orders,Long userId,String payType,String ip) {
        String prefix  = "ZFBBUY";
        if("2".equals(payType)){
            prefix  = "WXBUY";
        }
        // 设置请求参数
        String nowSrt = DateUtils.dateTimeNow();
        String outTradeNo = prefix + nowSrt;
        List<ArtOrder> artOrders = orders.getArtOrders();
        BigDecimal orderAmount = new BigDecimal(0);
        int i = 0;
        for(ArtOrder order : artOrders){
            String orderNoSrt = DateUtils.dateTimeNow();
            String orderNo = prefix + orderNoSrt + i;
            i++;
            ArtRental artRental = artRentalMapper.selectArtRentalById(order.getArtRentalId());
            if(ObjectUtil.isNull(artRental)) {
                return "商品不存在";
            }
            order.setOrderAmount(artRental.getPrice());
            BigDecimal price = order.getOrderAmount();
            orderAmount = orderAmount.add(price);

            order.setOrderName(DateUtils.getDate());
            order.setArtName(artRental.getArtName());
            Calendar calendar = Calendar.getInstance();
            Date currentDate = calendar.getTime();

            order.setOrderNo(orderNo);
            order.setOrderRequestNo(orderNo);

            if("2".equals(payType)){//微信支付
              //wechatOrder paymentMethod
                order.setWechatOrder(outTradeNo);
                order.setPaymentMethod("wx");
            }else if("1".equals(payType)){//支付宝支付
                order.setAliTradeNo(outTradeNo);
                order.setPaymentMethod("alipay");
            }else{
               throw new RuntimeException("支付方式错误");
            }
            order.setOrderStatus("0");//待确认
            order.setCreateTime(currentDate);
            order.setUpdateTime(currentDate);
            // 组装收货数据
            if(order.getUserAddressId() != null){
                ShippingAddresses shippingAddresses = shippingAddressesMapper.selectShippingAddressesById(order.getUserAddressId());
                String deliveryAddress = shippingAddresses.getStreetAddress() + shippingAddresses.getDistrict();
                order.setDeliveryAddress(deliveryAddress);
                order.setDeliveryName(shippingAddresses.getRecipientName());
                order.setDeliveryPhone(shippingAddresses.getPhoneNumber());
            }

        }

        if("2".equals(payType)){
            // 创建微信支付订单 Long userId,String tradeNo,String orderAmount,CartArtOrder orders
            String wxCartOrder = createWXCartOrder(userId, outTradeNo, orderAmount.toString(), orders, ip);
            for(ArtOrder order : artOrders){
                artOrderMapper.insertArtOrder(order);
            }
            return wxCartOrder;
        }else if("1".equals(payType)){
            // 创建支付宝支付订单 Long userId,String tradeNo,String orderAmount,CartArtOrder orders
            String result = createCartAlipayOrder(userId,outTradeNo,orderAmount.toString(),orders);
            if(result != null && !"".equals(result)) {
                JSONObject jsonObject = JSONObject.parseObject(result).getJSONObject("alipay_trade_create_response");

                if(jsonObject.getString("code").equals("10000")) {
                    for(ArtOrder order : artOrders){
                        artOrderMapper.insertArtOrder(order);
                    }
                    return jsonObject.getString("trade_no");
                }
            }
        }


        return "订单创建失败";

    }

    /**
     * 支付宝支付订单退款
     * @param order
     * @return
     */
    @Override
    public AjaxResult refundZFBBuyOrderOperate(ArtOrder order) {
        boolean refundFlag = zlipayOrderRefund(order);
        order.setOrderStatus("7");// 订单状态 7-退款处理中
        if(refundFlag) {
            order.setOrderStatus("8");// 订单状态 7-退款成功
        }
        artOrderMapper.updateByOrderNo(order);
        return AjaxResult.success("退款申请成功");
    }

    /**
     * 后台处理支付宝订单仅退款申请
     * @param order
     * @return
     */
    @Override
    public AjaxResult refundZFBOrderOperate(ArtOrder order) {
        ArtOrder artOrder = artOrderMapper.selectArtOrderByParam(order);
        if("1".equals(order.getOrderType())){ // 租赁订单
            return refundZmOrderOperate(artOrder);
        }

        return refundZFBBuyOrderOperate(artOrder);
    }

    /**
     * 租赁订单续租，手动续租
     * @param order
     * @return
     */
    @Transactional
    @Override
    public AjaxResult manualLeaseRenewal(ArtOrder order) {
        // 查询当前续租订单的完整数据
        ArtOrder tmpOrder = new ArtOrder();
        tmpOrder.setOrderNo(order.getOrderNo());
        tmpOrder = artOrderMapper.selectArtOrderByParam(tmpOrder);

        ArtOrder param = new ArtOrder();
        if(tmpOrder.getParentOrderNo() != null){
            param.setOrderNo(tmpOrder.getParentOrderNo());
        }else{
            param.setOrderNo(tmpOrder.getOrderNo());
        }

        // 查询主订单
        ArtOrder mainOrder = artOrderMapper.getManualExpireLeaseOrder(param);

        Integer currentRentalDays = order.getRentalDays(); // 当前续租天数，手动，从请求参数中获取

        ArtRental artRental = artRentalMapper.selectArtRentalById(mainOrder.getArtRentalId());

        Date[] dateArr = calculateDate(mainOrder, currentRentalDays);
        Date rentalStartDate = dateArr[0];
        Date rentalEndDate = dateArr[1];

        String result = checkLeaseRenewalZmOrder(mainOrder, artRental, currentRentalDays, false);
        if("success".equals(result)){
            // 组装续租订单数据
            ArtOrder renewalOrder = new ArtOrder();
            renewalOrder.setOrderNo(ORDER_PREFIX + DateUtils.dateTimeNow());
            renewalOrder.setOrderRequestNo(renewalOrder.getOrderNo());
            renewalOrder.setZmAuthOrderNo(mainOrder.getZmAuthOrderNo()); // 支付宝授权资金订单号
            renewalOrder.setAliOrder(mainOrder.getAliOrder()); // 支付宝的授权资金操作流水号
            if(mainOrder.getParentOrderNo() != null){
                renewalOrder.setParentOrderNo(mainOrder.getParentOrderNo());
            }else {
                renewalOrder.setParentOrderNo(mainOrder.getOrderNo());
            }
            renewalOrder.setOrderStatus("0"); // 订单状态，0待支付
            renewalOrder.setOrderType("1"); // 订单类型，1租赁
            renewalOrder.setArtRentalId(mainOrder.getArtRentalId()); // 商品ID
            renewalOrder.setArtName(mainOrder.getArtName()); // 商品名称
            renewalOrder.setRentalDays(currentRentalDays); // 续租的租期
            renewalOrder.setRentalStatus("0"); // 租赁状态，0-待确认
            renewalOrder.setOrderAmount(artRental.getRentalFee().multiply(new BigDecimal(currentRentalDays))); // 续租的租金
            renewalOrder.setRentalStartDate(rentalStartDate); // 续租的开始日期
            renewalOrder.setRentalEndDate(rentalEndDate); // 续租的结束日期
            renewalOrder.setCreateTime(new Date());
            renewalOrder.setUpdateTime(new Date());
            renewalOrder.setUserId(mainOrder.getUserId());

            // 扣款逻辑，只记录当期续租的数据不扣款，对上一期的续租订单进行扣款
            // 查询上一期的续租订单，如果存在，则扣款，因为当期续租订单还没有插入数据库，所以上一期就是续租订单的最后一个
            ArtOrder preRenewalOrder = null;

            if(mainOrder.getParentOrderNo() != null) {
                preRenewalOrder = mainOrder;
            }

            boolean zmChargebacksFlag = true;

            if(preRenewalOrder != null) {
                zmChargebacksFlag = zmChargebacks(preRenewalOrder); // 冻结资金部分扣款
            }

            if(zmChargebacksFlag) {
                renewalOrder.setRentalStatus("1"); // 租赁状态 1-租赁中
                renewalOrder.setOrderStatus("1"); // 订单状态 1-已支付
                artOrderMapper.insertArtOrder(renewalOrder); // 记录当期续租订单

//                mainOrder.setRentalDays(currentRentalDays + mainOrder.getRentalDays()); // 更新租期
//                mainOrder.setRentalEndDate(rentalEndDate); // 续租的结束日期
//                artOrderMapper.updateByOrderNo(mainOrder); // 更新主订单

                return AjaxResult.success("续租成功");
            }

            return AjaxResult.error("续租失败");
        }

        return AjaxResult.error(result);
    }

    /**
     * 客户不如期退还，自动按照每月续约扣费
     * 判断订单是是过7天未到扣款期归还的订单，如果是按照首期扣款
     */
    @Override
    public void autoNotReturnedTask(){
        // 1、查询售后表中，afterType=2归还状态，并且status=2售后中的订单
        ArtOrderAfter aa = new ArtOrderAfter();
        aa.setAfterType(2l);
        aa.setStatus(2l);
        List<ArtOrderAfter> artOrderAfterList = artOrderAfterMapper.selectArtOrderAfterList(aa);

        // 2、遍历售后订单，如果售后表上没有快递单号，根据订单号查询订单，对订单续租一个月
        for(ArtOrderAfter artOrderAfter : artOrderAfterList) {
            // 如果售后表有快递公司和快递单号，则不处理
            if(artOrderAfter.getNu() != null && artOrderAfter.getCom() != null){
                continue;
            }

            // 查询订单
            ArtOrder mainOrder = artOrderMapper.getOrderByOrderNo(artOrderAfter.getPlatOrderNo());

            // 如果当前订单是子订单，则查询父订单
            if(mainOrder.getParentOrderNo() != null){
                mainOrder = artOrderMapper.getOrderByOrderNo(mainOrder.getParentOrderNo());
            }

            /*
            进入售后有2种情况：
            1、正常归还
            2、提前归还
            都视为正常归还，提前归还的按照首租的规则处理，就是必须扣费，不管是否填写快递单号
            正常归还的，如果没有快递单号，继续续租一个月
             */
            // 判断订单是是过7天未到扣款期归还的订单，如果是按照首期扣款
            ArtServiceCharge artServiceCharge = artServiceChargeMapper.selectByOrderNo(mainOrder.getOrderNo());
            if(artServiceCharge != null){ // 存在服务费记录并且未扣费，不再扣款
                if(mainOrder.getOrderAmount() == null && "0".equals(artServiceCharge.getStatus())){
                    // 未扣款，则续租一个月
                    serviceChargeUtil(artServiceCharge);
                    continue;
                }

                // 如果已扣款并且订单结束时间大于等于本月，本次不处理
                if("1".equals(artServiceCharge.getStatus())) {
                    // 获取当前时间的Calendar
                    Calendar currentCalendar = Calendar.getInstance();
                    currentCalendar.setTime(new Date());

                    // 设置当前月的第一天
                    currentCalendar.set(Calendar.DAY_OF_MONTH, 1);

                    // 获取updateTime的Calendar
                    Calendar updateCalendar = Calendar.getInstance();
                    updateCalendar.setTime(mainOrder.getRentalEndDate());

                    if (!updateCalendar.before(currentCalendar)){
                        continue;
                    }
                }
            }


            // 查询订单商品的一天租金的总和
            ArtRental artRental = artRentalMapper.getTotalRentalFeeByIds(mainOrder.getCartRentalIds());

            // 获取当前日期
            Calendar calendar1 = Calendar.getInstance();
            calendar1.setTime(mainOrder.getRentalStartDate()); // 最开始日期

            Date rentalEndDateOld = mainOrder.getRentalEndDate(); // 历史租赁的结束日期

            // 2.1、查询当前租赁订单的续租订单列表，根据ID正序排序
            List<ArtOrder> renewalOrderList = artOrderMapper.getAutoRenewalOrderList(mainOrder);

            // 计算实际的历史租金总额
            BigDecimal totalAmount = mainOrder.getOrderAmount();

            // 2.2.1、如果存在续租订单，历史租赁的结束日期为最新续租订单的结束日期
            if(CollectionUtil.isNotEmpty(renewalOrderList)) {
                rentalEndDateOld = renewalOrderList.get(0).getRentalEndDate();
                for(ArtOrder renewalOrder : renewalOrderList) {
                    totalAmount = totalAmount.add(renewalOrder.getOrderAmount());
                }
            }
            Calendar calendar2 = Calendar.getInstance();
            calendar2.setTime(rentalEndDateOld); // 历史租赁的结束日期

            //计算历史租赁的总天数
            Long diffInMillisOld = calendar2.getTimeInMillis() - calendar1.getTimeInMillis();
            Long diffInDaysOld = diffInMillisOld / (24 * 60 * 60 * 1000); // 转换为天数
            diffInDaysOld = diffInDaysOld + 1; // 加1天，因为要包含本期开始时间

            // 计算历史租金总额，按照无折扣的普通租金来计算，不然买断的情况会出现问题
            BigDecimal totalAmountOld = new BigDecimal(diffInDaysOld).multiply(artRental.getRentalFee());

            // 2.3、计算本期续租租金，订单商品的单天租金*本月天数
            // 设置本期开始时间为历史租赁的结束日期+1天
            Calendar nowCalendarStart = Calendar.getInstance();
            nowCalendarStart.setTime(rentalEndDateOld);
            nowCalendarStart.add(Calendar.DAY_OF_MONTH, 1);

            // 设置本期结束时间为rentalEndDateOld+deductionCycle月，目前只支持1个月
            Calendar nowCalendarEnd = Calendar.getInstance();
            nowCalendarEnd.setTime(rentalEndDateOld);
            nowCalendarEnd.add(Calendar.MONTH, 1);
            // 设置为该月份的最后一天
            nowCalendarEnd.set(Calendar.DAY_OF_MONTH, nowCalendarEnd.getActualMaximum(Calendar.DAY_OF_MONTH));

            // 计算本期开始时间到本期结束时间的总天数
            Long nowDiffInMillis = nowCalendarEnd.getTimeInMillis() - nowCalendarStart.getTimeInMillis();
            Long nowDiffInDays = nowDiffInMillis / (24 * 60 * 60 * 1000); // 转换为天数
            nowDiffInDays = nowDiffInDays + 1; // 加1天，因为要包含本期开始时间

            // 计算本期应扣租金
            // 这里的租金单位要看是活动折扣还是他也就折扣还是普通租金
            BigDecimal dayRentalFeeReal = new BigDecimal(0);
            // 需要遍历订单的商品，累加计算，因为可能每个商品的折扣、特价、周期都不一样
            for(String cartRentalId : mainOrder.getCartRentalIds().split(",")){
                ArtRental rental = artRentalMapper.getTotalRentalFeeByIds(cartRentalId);
                if(rental.getActivityDiscountPrice() > 0){ // 存在活动折扣
                    dayRentalFeeReal = dayRentalFeeReal.add(artRental.getRentalFee().multiply(new BigDecimal(artRental.getActivityDiscountPrice())).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
                }else if(!"0.00".equals(artRental.getActivitySpecialPrice())){ // 存在特价
                    dayRentalFeeReal = dayRentalFeeReal.add(new BigDecimal(rental.getActivitySpecialPrice()));
                }else{
                    dayRentalFeeReal = dayRentalFeeReal.add(rental.getRentalFee());
                }
            }

            BigDecimal monthRentalFee = dayRentalFeeReal.multiply(new BigDecimal(nowDiffInDays));
            ArtDiscountCycle artDiscountCycle = new ArtDiscountCycle();
            artDiscountCycle.setLeaseCycle("1"); // 1表示1个月
            artDiscountCycle = artDiscountCycleMapper.getDiscountCycleByParam(artDiscountCycle); // 根据扣款周期，查询扣款比例
            BigDecimal deductionPercentage = new BigDecimal(artDiscountCycle.getLeaseDiscount());

            // 计算本期应扣租金，按照扣款比例来计算
            monthRentalFee = monthRentalFee.multiply(deductionPercentage).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);

            ArtOrder newOrder = new ArtOrder();

            // 系统消息
            ArtMessage artMessage = new ArtMessage();

            artMessage.setStatus("0");
            artMessage.setType("0");
            artMessage.setSender(0l); // 0表示系统发送
            artMessage.setReceiver(mainOrder.getUserId());
            artMessage.setSendTime(new Date());

            // 2.3.2、计算本期应扣租金
            // 计算之前累积租金与商品总价的差值
            BigDecimal subtractValue = artRental.getPrice().subtract(totalAmountOld);
            // 判断本期应扣租金是否大于差值，如果大于，则本期应扣租金等于之前累积租金与商品总价的差值并买断
            if(monthRentalFee.compareTo(subtractValue) > 0) {
                monthRentalFee = subtractValue;
                newOrder.setOrderType("2"); // 订单类型，2买断
                artMessage.setTitle("订单自动买断提醒");
                artMessage.setContent("您的租赁订单" + mainOrder.getOrderNo() + "在本月4号前未归还，再次续租的租金已经大于剩余的冻结金额，系统已自动买断，买断单号：" + mainOrder.getOrderNo());
            }else {
                newOrder.setOrderType("1"); // 订单类型，1租赁
                artMessage.setTitle("订单自动续租提醒");
                artMessage.setContent("您的租赁订单" + mainOrder.getOrderNo() + "在本月4号前未归还，系统已自动续租1个月");
            }

            newOrder.setOrderAmount(monthRentalFee); // 续租的租金
            newOrder.setOrderNo(ORDER_PREFIX + DateUtils.dateTimeNow());
            newOrder.setOrderRequestNo(newOrder.getOrderNo());
            newOrder.setZmAuthOrderNo(mainOrder.getZmAuthOrderNo()); // 支付宝授权资金订单号
            newOrder.setAliOrder(mainOrder.getAliOrder()); // 支付宝的授权资金操作流水号
            newOrder.setParentOrderNo(mainOrder.getOrderNo());
            newOrder.setOrderStatus("1"); // 订单状态，1-已支付
            newOrder.setCartRentalIds(mainOrder.getCartRentalIds()); // 商品ID
            newOrder.setArtName(mainOrder.getArtName()); // 商品名称
            newOrder.setCreateTime(new Date());
            newOrder.setUpdateTime(new Date());
            newOrder.setUserId(mainOrder.getUserId());
            newOrder.setRentalStatus("0"); // 租赁状态，0-待确认

            // 2.4、更新订单表，设置首期租金并扣款
            // 2.4.1、如果是普通支付的租赁订单，直接把order_amount修改成扣款金额不用扣款，AliTradeNo是支付宝普通支付的交易号
            if(mainOrder.getAliTradeNo() != null){
                if("2".equals(mainOrder.getOrderType())){ // 如果是买断订单，把主订单状态设置为完成状态
                    // 计算需要退款的金额
                    BigDecimal refundAmount = artRental.getPrice().subtract(totalAmount.add(monthRentalFee));
                    mainOrder.setRefundAmount(refundAmount);
                    mainOrder.setOrderStatus("7"); // 订单状态 7-退款处理中
                    // 退款操作
                    boolean b = zlipayOrderRefund(mainOrder);
                    if(b) {
                        mainOrder.setOrderStatus("6"); // 订单状态 6-已完成
                        artOrderMapper.updateByOrderNo(mainOrder); // 更新主订单
                    }
                }else {
                    newOrder.setRentalStartDate(nowCalendarStart.getTime()); // 续租的开始日期
                    newOrder.setRentalEndDate(nowCalendarEnd.getTime()); // 续租的结束日期
                }
                artOrderMapper.insertArtOrder(newOrder);
            }else{
                // 2.4.2、如果是支付宝预授权的租赁订单，需要调用支付宝芝麻信用接口扣款，扣款成功后才可以修改order_amount
                boolean zmChargebacksFlag =  zmChargebacks(newOrder); // 冻结资金部分扣款
                if(zmChargebacksFlag){ // 扣款成功
                    if("2".equals(mainOrder.getOrderType())){ // 如果是买断订单，把完成主订单并解冻剩余金额
                        completeZmOrder(mainOrder); // 完成支付宝预授权的租赁订单，同时解冻剩余金额
                    }else {
                        newOrder.setRentalStartDate(nowCalendarStart.getTime()); // 续租的开始日期
                        newOrder.setRentalEndDate(nowCalendarEnd.getTime()); // 续租的结束日期
                    }
                }else{ // 扣款失败
                    log.error("自动续租失败，订单号：{}", newOrder.getOrderNo());
                    newOrder.setOrderStatus("88"); // 订单状态 88-需要手动支付
                    newOrder.setRecoveryStatus("1"); // 1-追缴未支付
                    newOrder.setAliTradeNo(newOrder.getOrderNo()); // 设置创建支付宝订单的交易号
                    newOrder.setRecoveryReason("该续租订单租金扣除失败，请及时支付"); // 追缴原因
                }
                artOrderMapper.insertArtOrder(newOrder);
            }
            artMessageMapper.insertArtMessage(artMessage);
        }
    }

    /**
     * 自动续租定时任务
     */
    @Override
    public void autoLeaseRenewalTask(){
        // 1、查询所有待续租的租赁订单，
        // 有签收日期sign_date!=null，并且有订单金额order_amount!=null的，
        // 并且afterStatus=0没有售后的，并且recoveryStatus=0没有追缴的，
        // 并且order_status=1已支付的，并且order_type=1租赁的
        // 并且当前日期到 rentalEndDate的月份差值是deductionCycle的整数倍，并且rentalEndDate小于当前日期
        List<ArtOrder> mainOrderList = artOrderMapper.getAutoRenewalMainOrderList(new ArtOrder());

        // 2、遍历所有待续租的租赁订单
        for(ArtOrder mainOrder : mainOrderList) {
            // 查询订单商品的一天租金的总和
            ArtRental artRental = artRentalMapper.getTotalRentalFeeByIds(mainOrder.getCartRentalIds());

            // 获取当前日期
            Calendar calendar1 = Calendar.getInstance();
            calendar1.setTime(mainOrder.getRentalStartDate()); // 最开始日期

            Date rentalEndDateOld = mainOrder.getRentalEndDate(); // 历史租赁的结束日期

            // 2.1、查询当前租赁订单的续租订单列表，根据ID正序排序
            List<ArtOrder> renewalOrderList = artOrderMapper.getAutoRenewalOrderList(mainOrder);

            // 计算实际的历史租金总额
            BigDecimal totalAmount = mainOrder.getOrderAmount();

            // 2.2.1、如果存在续租订单，历史租赁的结束日期为最新续租订单的结束日期
            if(CollectionUtil.isNotEmpty(renewalOrderList)) {
                rentalEndDateOld = renewalOrderList.get(0).getRentalEndDate();
                for(ArtOrder renewalOrder : renewalOrderList) {
                    totalAmount = totalAmount.add(renewalOrder.getOrderAmount());
                }
            }
            Calendar calendar2 = Calendar.getInstance();
            calendar2.setTime(rentalEndDateOld); // 历史租赁的结束日期

            //计算历史租赁的总天数
            Long diffInMillisOld = calendar2.getTimeInMillis() - calendar1.getTimeInMillis();
            Long diffInDaysOld = diffInMillisOld / (24 * 60 * 60 * 1000); // 转换为天数
            diffInDaysOld = diffInDaysOld + 1; // 加1天，因为要包含本期开始时间

            // 计算历史租金总额，按照无折扣的普通租金来计算，不然买断的情况会出现问题
            BigDecimal totalAmountOld = new BigDecimal(diffInDaysOld).multiply(artRental.getRentalFee());

            // 2.3、计算本期续租租金，订单商品的单天租金*本月天数
            // 设置本期开始时间为历史租赁的结束日期+1天
            Calendar nowCalendarStart = Calendar.getInstance();
            nowCalendarStart.setTime(rentalEndDateOld);
            nowCalendarStart.add(Calendar.DAY_OF_MONTH, 1);

            // 设置本期结束时间为rentalEndDateOld+deductionCycle月
            Calendar nowCalendarEnd = Calendar.getInstance();
            nowCalendarEnd.setTime(rentalEndDateOld);
            nowCalendarEnd.add(Calendar.MONTH, Integer.parseInt(mainOrder.getDeductionCycle()));
            // 设置为该月份的最后一天
            nowCalendarEnd.set(Calendar.DAY_OF_MONTH, nowCalendarEnd.getActualMaximum(Calendar.DAY_OF_MONTH));

            // 计算本期开始时间到本期结束时间的总天数
            Long nowDiffInMillis = nowCalendarEnd.getTimeInMillis() - nowCalendarStart.getTimeInMillis();
            Long nowDiffInDays = nowDiffInMillis / (24 * 60 * 60 * 1000); // 转换为天数
            nowDiffInDays = nowDiffInDays + 1; // 加1天，因为要包含本期开始时间

            // 计算本期应扣租金
            // 这里的租金单位要看是活动折扣还是他也就折扣还是普通租金
            BigDecimal dayRentalFeeReal = new BigDecimal(0);
            // 需要遍历订单的商品，累加计算，因为可能每个商品的折扣、特价、周期都不一样
            for(String cartRentalId : mainOrder.getCartRentalIds().split(",")){
                ArtRental rental = artRentalMapper.getTotalRentalFeeByIds(cartRentalId);
                if(rental.getActivityDiscountPrice() > 0){ // 存在活动折扣
                    dayRentalFeeReal = dayRentalFeeReal.add(artRental.getRentalFee().multiply(new BigDecimal(artRental.getActivityDiscountPrice())).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
                }else if(!"0.00".equals(artRental.getActivitySpecialPrice())){ // 存在特价
                    dayRentalFeeReal = dayRentalFeeReal.add(new BigDecimal(rental.getActivitySpecialPrice()));
                }else{
                    dayRentalFeeReal = dayRentalFeeReal.add(rental.getRentalFee());
                }
            }

            BigDecimal monthRentalFee = dayRentalFeeReal.multiply(new BigDecimal(nowDiffInDays));
            ArtDiscountCycle artDiscountCycle = new ArtDiscountCycle();
            artDiscountCycle.setLeaseCycle(mainOrder.getDeductionCycle());
            artDiscountCycle = artDiscountCycleMapper.getDiscountCycleByParam(artDiscountCycle); // 根据扣款周期，查询扣款比例
            BigDecimal deductionPercentage = new BigDecimal(artDiscountCycle.getLeaseDiscount());

            // 计算本期应扣租金，按照扣款比例来计算
            monthRentalFee = monthRentalFee.multiply(deductionPercentage).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);

            ArtOrder newOrder = new ArtOrder();

            // 系统消息
            ArtMessage artMessage = new ArtMessage();

            artMessage.setStatus("0");
            artMessage.setType("0");
            artMessage.setSender(0l); // 0表示系统发送
            artMessage.setReceiver(mainOrder.getUserId());
            artMessage.setSendTime(new Date());

            // 2.3.2、计算本期应扣租金
            // 计算之前累积租金与商品总价的差值
            BigDecimal subtractValue = artRental.getPrice().subtract(totalAmountOld);
            // 判断本期应扣租金是否大于差值，如果大于，则本期应扣租金等于之前累积租金与商品总价的差值并买断
            if(monthRentalFee.compareTo(subtractValue) > 0) {
                monthRentalFee = subtractValue;
                newOrder.setOrderType("2"); // 订单类型，2买断
                artMessage.setTitle("订单自动买断提醒");
                artMessage.setContent("您的租赁订单" + mainOrder.getOrderNo() + "在本月4号前未归还，再次续租的租金已经大于剩余的冻结金额，系统已自动买断，买断单号：" + mainOrder.getOrderNo());
            }else {
                newOrder.setOrderType("1"); // 订单类型，1租赁
                artMessage.setTitle("订单自动续租提醒");
                artMessage.setContent("您的租赁订单" + mainOrder.getOrderNo() + "在本月4号前未归还，系统已自动续租" + mainOrder.getDeductionCycle() + "个月");
            }

            newOrder.setOrderAmount(monthRentalFee); // 续租的租金
            newOrder.setOrderNo(ORDER_PREFIX + DateUtils.dateTimeNow());
            newOrder.setOrderRequestNo(newOrder.getOrderNo());
            newOrder.setZmAuthOrderNo(mainOrder.getZmAuthOrderNo()); // 支付宝授权资金订单号
            newOrder.setAliOrder(mainOrder.getAliOrder()); // 支付宝的授权资金操作流水号
            newOrder.setParentOrderNo(mainOrder.getOrderNo());
            newOrder.setOrderStatus("1"); // 订单状态，1-已支付
            newOrder.setCartRentalIds(mainOrder.getCartRentalIds()); // 商品ID
            newOrder.setArtName(mainOrder.getArtName()); // 商品名称
            newOrder.setCreateTime(new Date());
            newOrder.setUpdateTime(new Date());
            newOrder.setUserId(mainOrder.getUserId());
            newOrder.setRentalStatus("0"); // 租赁状态，0-待确认

            // 2.4、更新订单表，设置首期租金并扣款
            // 2.4.1、如果是普通支付的租赁订单，直接把order_amount修改成扣款金额不用扣款，AliTradeNo是支付宝普通支付的交易号
            if(mainOrder.getAliTradeNo() != null){
                if("2".equals(mainOrder.getOrderType())){ // 如果是买断订单，把主订单状态设置为完成状态
                    // 计算需要退款的金额
                    BigDecimal refundAmount = artRental.getPrice().subtract(totalAmount.add(monthRentalFee));
                    mainOrder.setRefundAmount(refundAmount);
                    mainOrder.setOrderStatus("7"); // 订单状态 7-退款处理中
                    // 退款操作
                    boolean b = zlipayOrderRefund(mainOrder);
                    if(b) {
                        mainOrder.setOrderStatus("6"); // 订单状态 6-已完成
                        artOrderMapper.updateByOrderNo(mainOrder); // 更新主订单
                    }
                }else {
                    newOrder.setRentalStartDate(nowCalendarStart.getTime()); // 续租的开始日期
                    newOrder.setRentalEndDate(nowCalendarEnd.getTime()); // 续租的结束日期
                }
                artOrderMapper.insertArtOrder(newOrder);
            }else{
                // 2.4.2、如果是支付宝预授权的租赁订单，需要调用支付宝芝麻信用接口扣款，扣款成功后才可以修改order_amount
                boolean zmChargebacksFlag =  zmChargebacks(newOrder); // 冻结资金部分扣款
                if(zmChargebacksFlag){ // 扣款成功
                    if("2".equals(mainOrder.getOrderType())){ // 如果是买断订单，把完成主订单并解冻剩余金额
                        completeZmOrder(mainOrder); // 完成支付宝预授权的租赁订单，同时解冻剩余金额
                    }else {
                        newOrder.setRentalStartDate(nowCalendarStart.getTime()); // 续租的开始日期
                        newOrder.setRentalEndDate(nowCalendarEnd.getTime()); // 续租的结束日期
                    }
                }else{ // 扣款失败
                    log.error("自动续租失败，订单号：{}", newOrder.getOrderNo());
                    newOrder.setOrderStatus("88"); // 订单状态 88-需要手动支付
                    newOrder.setRecoveryStatus("1"); // 1-追缴未支付
                    newOrder.setAliTradeNo(newOrder.getOrderNo()); // 设置创建支付宝订单的交易号
                    newOrder.setRecoveryReason("该续租订单租金扣除失败，请及时支付"); // 追缴原因
                }
                artOrderMapper.insertArtOrder(newOrder);
            }
            artMessageMapper.insertArtMessage(artMessage);
        }
    }

    /**
     * 自动确认收货定时任务，自订单签收之日起第4天执行，也就是签收日期与当天的日期差值是3天以上的订单
     */
    @Override
    public void autoConfirmReceiptTask() {
        ArtOrder orderParam = new ArtOrder();
        orderParam.setOrderStatus("2"); // 订单状态 2-已支付
         // 查询所有已签收的租赁订单并且没有确认收货的订单
        List<ArtOrder> notConfirmOrderList = artOrderMapper.selectNotConfirmOrderList(orderParam);
        for(ArtOrder order : notConfirmOrderList) {
            // 购买订单确认收货就是完成，租赁订单需要平台确认归还或者买断才算完成
            if(order.getOrderType().equals("2")){
                order.setOrderStatus("6"); // 订单状态 6-已完成
            }
            order.setConfirmDate(new Date()); // 确认收货时间
            artOrderMapper.updateByOrderNo(order);
        }
    }

    /**
     *  确认收货
     * @param order
     * @return
     */
    @Override
    public AjaxResult confirmReceipt(ArtOrder order) {
        ArtOrder artOrder = artOrderMapper.selectArtOrderByParam(order);
        // 购买订单确认收货就是完成，租赁订单需要平台确认归还或者买断才算完成
        if(artOrder.getOrderType().equals("2")){
            order.setOrderStatus("6"); // 订单状态 6-已完成
        }
        order.setConfirmDate(new Date()); // 确认收货时间
        return artOrderMapper.updateByOrderNo(order) > 0? AjaxResult.success() : AjaxResult.error();
    }


    /**
     * 手动买断
     * @param order
     * @return
     */
    @Override
    public AjaxResult manualMaiduan(ArtOrder order) {
        // 查询当前续租订单的完整数据
        ArtOrder tmpOrder = artOrderMapper.selectArtOrderByParam(order);

        // 查询主订单
        ArtOrder mainOrder = new ArtOrder();

        // 当前续租订单不是主订单，根据主订单号查询主订单
        if(tmpOrder.getParentOrderNo() != null && !"".equals(tmpOrder.getParentOrderNo())){
            mainOrder.setOrderNo(tmpOrder.getParentOrderNo());
            mainOrder = artOrderMapper.selectArtOrderByParam(mainOrder);
        }else{
            mainOrder = tmpOrder; // 当前续租订单就是主订单
        }

        String zmOrderString = zmnDetail(mainOrder);
        JSONObject zmOrder = JSONObject.parseObject(zmOrderString).getJSONObject("alipay_fund_auth_operation_detail_query_response");
        if(zmOrder.getString("code").equals("10000")) {
            // 订单当前剩余冻结金额，单位为：元
            String restAmount = zmOrder.getString("rest_amount");
            // 组装续租订单数据
            ArtOrder renewalOrder = new ArtOrder();
            renewalOrder.setOrderNo(ORDER_PREFIX + DateUtils.dateTimeNow());
            renewalOrder.setOrderRequestNo(renewalOrder.getOrderNo());
            renewalOrder.setZmAuthOrderNo(mainOrder.getZmAuthOrderNo());

            if(mainOrder.getParentOrderNo() != null){
                renewalOrder.setParentOrderNo(mainOrder.getParentOrderNo());
            }else {
                renewalOrder.setParentOrderNo(mainOrder.getOrderNo());
            }

            renewalOrder.setOrderStatus("0"); // 订单状态，0待支付
            renewalOrder.setOrderType("2"); // 订单类型，2购买
            renewalOrder.setArtRentalId(mainOrder.getArtRentalId()); // 商品ID
            renewalOrder.setArtName(mainOrder.getArtName()); // 商品名称
            renewalOrder.setOrderAmount(new BigDecimal(restAmount)); // 剩余的冻结金额作为商品售价
            renewalOrder.setCreateTime(new Date());
            renewalOrder.setUpdateTime(new Date());
            renewalOrder.setUserId(mainOrder.getUserId());

            boolean zmChargebacksFlag =  zmChargebacks(renewalOrder); // 冻结资金部分扣款

            if(zmChargebacksFlag) {
                renewalOrder.setOrderStatus("6"); // 订单状态 6-完成
                artOrderMapper.insertArtOrder(renewalOrder);

                mainOrder.setOrderStatus("6"); // 订单状态 6-完成
                artOrderMapper.updateByOrderNo(mainOrder); // 更新主订单状态
                return AjaxResult.success("买断成功");
            }

            return AjaxResult.error("买断失败");
        }else {

            return AjaxResult.error("查询免押订单失败");
        }
    }



    /**
     * 买断公共方法
     * @param mainOrder
     * @return
     */
    @Override
    public AjaxResult maiduan(ArtOrder mainOrder) {
        String zmOrderString = zmnDetail(mainOrder);
        JSONObject zmOrder = JSONObject.parseObject(zmOrderString).getJSONObject("alipay_fund_auth_operation_detail_query_response");
        if(zmOrder.getString("code").equals("10000")) {
            // 订单当前剩余冻结金额，单位为：元
            String restAmount = zmOrder.getString("rest_amount");
            // 组装续租订单数据
            ArtOrder renewalOrder = new ArtOrder();
            renewalOrder.setOrderNo(ORDER_PREFIX + DateUtils.dateTimeNow());
            renewalOrder.setOrderRequestNo(renewalOrder.getOrderNo());
            renewalOrder.setZmAuthOrderNo(mainOrder.getZmAuthOrderNo());

            if(mainOrder.getParentOrderNo() != null){
                renewalOrder.setParentOrderNo(mainOrder.getParentOrderNo());
            }else {
                renewalOrder.setParentOrderNo(mainOrder.getOrderNo());
            }

            renewalOrder.setOrderStatus("0"); // 订单状态，0待支付
            renewalOrder.setOrderType("2"); // 订单类型，2购买
            renewalOrder.setArtRentalId(mainOrder.getArtRentalId()); // 商品ID
            renewalOrder.setArtName(mainOrder.getArtName()); // 商品名称
            renewalOrder.setOrderAmount(new BigDecimal(restAmount)); // 剩余的冻结金额作为商品售价
            renewalOrder.setCreateTime(new Date());
            renewalOrder.setUpdateTime(new Date());
            renewalOrder.setUserId(mainOrder.getUserId());

            boolean zmChargebacksFlag =  zmChargebacks(renewalOrder); // 冻结资金部分扣款

            if(zmChargebacksFlag) {
                renewalOrder.setOrderStatus("6"); // 订单状态 1-已支付
                artOrderMapper.insertArtOrder(renewalOrder);

                mainOrder.setOrderStatus("6"); // 订单状态 6-完成
                artOrderMapper.updateByOrderNo(mainOrder); // 更新主订单状态

                return AjaxResult.success("买断成功");
            }

            return AjaxResult.error("买断失败");
        }else {

            return AjaxResult.error("查询免押订单失败");
        }
    }

    /**
     * 更新订单的免押授权编号，同时扣除免押订单中的租金部分
     * @param message
     * @return
     */
    @Transactional
    @Override
    public AjaxResult callbackZmOrder(String message) {
        JSONObject jsonObject = JSONObject.parseObject(message);
        log.info("支付宝回调参数:{}",jsonObject);

        String resultCode = jsonObject.getString("resultCode");
        if("9000".equals(resultCode)){
            ArtOrder artOrder = new ArtOrder();

            try{
                JSONObject result = jsonObject.getJSONObject("result").getJSONObject("alipay_fund_auth_order_app_freeze_response");
                String authNo = result.getString("auth_no");
                String orderNo = result.getString("out_order_no");
                artOrder.setOrderNo(orderNo);

                artOrder = artOrderMapper.selectArtOrderByParam(artOrder);

                artOrder.setZmAuthOrderNo(authNo);
            }catch (Exception e){
                String authNo = jsonObject.getJSONObject("extendInfo").getString("tradeNo");
                ArtOrder param = new ArtOrder();
                param.setZmAuthOrderNo(authNo);
                artOrder = artOrderMapper.selectArtOrderByParam(param);
            }

            // 扣款
            boolean zmChargebacksFlag = zmChargebacks(artOrder);

            if(!zmChargebacksFlag) {
                artOrder.setOrderStatus("999"); // 订单状态 999-删除

                // 取消免押订单
                boolean zmCancelFlag = zmCancel(artOrder);

                if(zmCancelFlag) {
                    // 扣款失败，逻辑删除订单
                    artOrderMapper.updateByOrderNo(artOrder);
                }

                return AjaxResult.error("免押扣款失败");
            }

            artOrder.setRentalStatus("1"); // 租赁状态 1-租赁中
            artOrder.setOrderStatus("1"); // 订单状态 1-已支付
            // 更新订单状态
            int i = artOrderMapper.updateByOrderNo(artOrder);
            return AjaxResult.success();
        }
        return AjaxResult.error("支付宝回调失败");
    }

    /**
     * 手动完成免押订单，小程序端使用
     * @param order
     * @return
     */
    @Override
    public AjaxResult manualCompleteZmOrder(ArtOrder order) {
        ArtOrder artOrder = artOrderMapper.selectArtOrderByParam(order);

        ArtOrder param = new ArtOrder();

        param.setParentOrderNo(artOrder.getOrderNo());
        if(artOrder.getParentOrderNo() != null){
            param.setParentOrderNo(artOrder.getParentOrderNo());
        }

        param.setOrderType("1");
        param.setOrderStatus("2");
        List<ArtOrder> childOrders = artOrderMapper.selectArtOrderSortById(param);

        ArtOrder lastChildOrder = childOrders.get(childOrders.size() - 1);

        // 查询这个续租订单是否已经扣款
        String zlipayOrderDetail = zlipayOrderDetail(lastChildOrder);
        JSONObject zlipayOrderDetailJson = JSONObject.parseObject(zlipayOrderDetail).getJSONObject("alipay_trade_query_response");

        boolean isPaid = false;
        if("10000".equals(zlipayOrderDetailJson.getString("code"))){
            if("TRADE_SUCCESS".equals(zlipayOrderDetailJson.getString("trade_status"))){
                // 订单已经扣款，直接完成订单
                isPaid = true;
            }
        }

        // 如果续租订单没有扣款，则去扣款
        if(!isPaid) {
            // 对最后一个续租订单进行扣款操作
            boolean zmChargebacksFlag = zmChargebacks(lastChildOrder);

            if(!zmChargebacksFlag) {
                return AjaxResult.error("续租订单扣款失败，无法完成免押订单");
            }

        }

        String zmOrderString = zmnDetail(artOrder);
        JSONObject zmOrder = JSONObject.parseObject(zmOrderString).getJSONObject("alipay_fund_auth_operation_detail_query_response");
        if(zmOrder.getString("code").equals("10000")) {
            // 订单当前剩余冻结金额，单位为：元
            String restAmount = zmOrder.getString("rest_amount");
            order.setRestAmount(restAmount);
            order.setUnfreezeAmount(new BigDecimal(restAmount)); // 解冻金额，等于剩余冻结金额
            boolean zmnfreezeFlag =  zmnfreeze(order);

            if(zmnfreezeFlag) {
                order.setRentalStatus("2"); // 租赁状态 2-已归还
                order.setOrderStatus("6"); // 订单状态 6-完成
                artOrderMapper.updateByOrderNo(order);
                return AjaxResult.success("完成免押订单成功");
            }

            return AjaxResult.error("完成免押订单失败");
        }else {
            return AjaxResult.error("查询免押订单失败");
        }
    }

    @Override
    public String getRest_amount(String orderNo) {
        String restAmount ="0";
        ArtOrder artOrder = artOrderMapper.getOrderByOrderNo(orderNo);
        if(StringUtil.isNotEmpty(artOrder.getParentOrderNo())) {//如果没有父订单号，说明是首单
            artOrder = artOrderMapper.getOrderByOrderNo(artOrder.getParentOrderNo());
        }
        String zmOrderString = zmnDetail(artOrder);
        JSONObject zmOrder = JSONObject.parseObject(zmOrderString).getJSONObject("alipay_fund_auth_operation_detail_query_response");
        if(zmOrder.getString("code").equals("10000")) {
            restAmount = zmOrder.getString("rest_amount");
        }
        return restAmount;
    }

    @Override
    public Map<String, Integer> getWeekArtCount() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startDate = now.minusDays(7).withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime endDate = now.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
        Map<String ,Integer> map = new HashMap<>();
        List<ArtOrder> artOrders = artOrderMapper.selectArtOrderListInDate(startDate, endDate);
        for (ArtOrder artOrder : artOrders) {
            String k = DateUtils.parseDateToStr("yyyy-MM-dd", artOrder.getCreateTime());
            Integer val = map.get(k);
            map.put(k, val == null? 1 : val + 1);
        }
        return map;
    }

    @Override
    public Map<String, Integer> getMonthArtCount() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startDate = now.minusDays(30).withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime endDate = now.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
        Map<String ,Integer> map = new HashMap<>();
        List<ArtOrder> artOrders = artOrderMapper.selectArtOrderListInDate(startDate, endDate);
        for (ArtOrder artOrder : artOrders) {
            String k = DateUtils.parseDateToStr("yyyy-MM-dd", artOrder.getCreateTime());
            Integer val = map.get(k);
            map.put(k, val == null? 1 : val + 1);
        }
        return map;
    }

    @Override
    public Map<String, Integer> getYearArtCount() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startDate = now.minusMonths(12).withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime endDate = now.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
        Map<String ,Integer> map = new HashMap<>();
        List<ArtOrder> artOrders = artOrderMapper.selectArtOrderListInDate(startDate, endDate);
        for (ArtOrder artOrder : artOrders) {
            String k = DateUtils.parseDateToStr("yyyy-MM", artOrder.getCreateTime());
            Integer val = map.get(k);
            map.put(k, val == null? 1 : val + 1);
        }
        return map;

    }
    public List<ArtOrder> appCarouselList() {
        return artOrderMapper.appCarouselList();
    }

    /**
     * 完成免押订单
     * @param order
     * @return
     */
    @Override
    public AjaxResult completeZmOrder(ArtOrder order) {
       // ArtOrder artOrder = artOrderMapper.selectArtOrderByParam(order);
        ArtOrder artOrder = artOrderMapper.getOrderByOrderNo(order.getOrderNo());
        String zmOrderString = zmnDetail(artOrder);
        JSONObject zmOrder = JSONObject.parseObject(zmOrderString).getJSONObject("alipay_fund_auth_operation_detail_query_response");
        if(zmOrder.getString("code").equals("10000")) {
            // 订单当前剩余冻结金额，单位为：元
            String restAmount = zmOrder.getString("rest_amount");
            order.setRestAmount(restAmount);
            order.setUnfreezeAmount(new BigDecimal(restAmount)); // 解冻金额，等于剩余冻结金额
            boolean zmnfreezeFlag =  zmnfreeze(order);

            if(zmnfreezeFlag) {
                order.setUnfreezeAmount(null);
                order.setRentalStatus("2"); // 租赁状态 2-已归还
                order.setOrderStatus("6"); // 订单状态 6-完成
                artOrderMapper.updateByOrderNo(order);

                // 完成主订单
                if(order.getParentOrderNo() != null){
                    ArtOrder parentOrder = new ArtOrder();
                    parentOrder.setOrderNo(order.getParentOrderNo());
                    parentOrder.setOrderStatus("6"); // 订单状态 6-完成
                    artOrderMapper.updateByOrderNo(parentOrder);
                }
                return AjaxResult.success("完成免押订单成功");
            }

            return AjaxResult.error("完成免押订单失败");
        }else {
            return AjaxResult.error("查询免押订单失败");
        }
    }

    /**
     * 售后那里用到的结束订单
     * */
    @Override
    public boolean afterCompleteZmOrder(ArtOrder order) {
        ArtOrder artOrder = artOrderMapper.selectArtOrderByParam(order);
        String zmOrderString = zmnDetail(artOrder);
        JSONObject zmOrder = JSONObject.parseObject(zmOrderString).getJSONObject("alipay_fund_auth_operation_detail_query_response");
        if(zmOrder.getString("code").equals("10000")) {
            // 订单当前剩余冻结金额，单位为：元
            String restAmount = zmOrder.getString("rest_amount");
            artOrder.setRestAmount(restAmount);
            artOrder.setUnfreezeAmount(new BigDecimal(restAmount)); // 解冻金额，等于剩余冻结金额
            boolean zmnfreezeFlag =  zmnfreeze(artOrder);

            if(zmnfreezeFlag) {
                artOrder.setRentalStatus("2"); // 租赁状态 2-已归还
                artOrder.setOrderStatus("6"); // 订单状态 6-完成
                artOrderMapper.updateByOrderNo(artOrder);
                return true;
            }

            return false;
        }else {
            return false;
        }
    }

    @Override
    public AjaxResult cancelLeaseRenewal(ArtOrder order) {
        ArtOrder artOrder = artOrderMapper.getOrderByOrderNo(order.getOrderNo());
        Date currentTime = new Date(); // 获取当前时间

        // 计算时间差
        long timeDifference = currentTime.getTime() - artOrder.getCreateTime().getTime();

        // 将时间差转换为小时
        long hoursDifference = timeDifference / (1000 * 60 * 60);

        // 如果时间差小于1小时，则不能取消
        if(hoursDifference > 1){
            return AjaxResult.error("当前订单已经下单超过1小时，不能取消");
        }

        String zmOrderString = zmnDetail(artOrder);
        JSONObject zmOrder = JSONObject.parseObject(zmOrderString).getJSONObject("alipay_fund_auth_operation_detail_query_response");
        if(zmOrder.getString("code").equals("10000")) {
            // 订单当前剩余冻结金额，单位为：元
            String restAmount = zmOrder.getString("rest_amount");
            artOrder.setRestAmount(restAmount);
            artOrder.setUnfreezeAmount(new BigDecimal(restAmount)); // 解冻金额，等于剩余冻结金额
            boolean zmnfreezeFlag =  zmnfreeze(artOrder);

            if(zmnfreezeFlag) {
                artOrder.setRentalStatus("2"); // 租赁状态 2-已归还
                artOrder.setOrderStatus("2"); // 订单状态 2-取消
                artOrderMapper.updateByOrderNo(artOrder);
                return AjaxResult.success("取消订单成功");
            }

            return AjaxResult.error("取消订单失败");
        }else {
            return AjaxResult.error("查询免押订单失败");
        }

    }

    /**
     * 退款申请
     * @param order
     * @return
     */
    @Override
    public AjaxResult refundZmOrder(ArtOrder order) {
        ArtOrder artOrder = new ArtOrder();
        artOrder.setOrderNo(order.getOrderNo());
        artOrder = artOrderMapper.selectArtOrderByParam(artOrder);
        artOrder.setOrderStatus(order.getOrderStatus());// 订单状态 3-退款申请
        int i = artOrderMapper.updateByOrderNo(artOrder);
        addGoodsNum(artOrder); // 增加商品数量
        if(i > 0) {
            return AjaxResult.success("退款申请成功");
        }
        return AjaxResult.error("退款申请失败");
    }

    /**
     * 退款处理
     * @param order
     * @return
     */
    @Override
    public AjaxResult refundZmOrderOperate(ArtOrder order) {
        boolean zmRefundFlag = zmnRefund(order);
        if(zmRefundFlag) {
            order.setOrderStatus("7");// 订单状态 7-退款处理中
            artOrderMapper.updateByOrderNo(order);
            return AjaxResult.success("退款申请成功");
        }
        return AjaxResult.error("退款申请失败");
    }

    /**
     * 免押扣款
     * @param order
     */
    @Override
    public boolean zmChargebacks(ArtOrder order) {
        boolean result = false;
//        ArtOrder order = artOrderMapper.selectArtOrderByParam(artOrder);

        AlipayTradePayRequest request = new AlipayTradePayRequest();
        AlipayTradePayModel model = new AlipayTradePayModel();

        // 设置商户订单号
        model.setOutTradeNo(order.getOrderNo());
//        if(order.getParentOrderNo() != null){
//            model.setOutTradeNo(order.getParentOrderNo()); // 续租订单从主订单扣款
//        }

        // 设置订单总金额
        model.setTotalAmount(order.getOrderAmount().toString());

        // 设置订单标题
        model.setSubject(order.getArtName() +"租金");

        // 设置资金预授权单号
        model.setAuthNo(order.getZmAuthOrderNo());

        // 设置产品码
        model.setProductCode("PREAUTH_PAY");

//        request.setBizModel(model);

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", order.getOrderNo());
        bizContent.put("total_amount", order.getOrderAmount().toString());
        bizContent.put("subject", order.getArtName() +"租金");
        bizContent.put("auth_no", order.getZmAuthOrderNo());
        bizContent.put("product_code", "PREAUTH_PAY");
//        bizContent.put("enable_pay_channels", "balance");

        request.setBizContent(bizContent.toString());

        try {
            AlipayClient alipayClient = aliConfigService.client();

//            log.info("免押扣款请求参数:{}",request.getBizModel().toString());
            log.info("免押扣款请求参数:{}",request.getBizContent().toString());

            // 调用接口扣款
            AlipayTradePayResponse response = alipayClient.execute(request);

            log.info("免押扣款接口返回结果:{}",response.getBody());

            if (response.isSuccess()) {
                JSONObject resultObj = JSONObject.parseObject(response.getBody()).getJSONObject("alipay_trade_pay_response");
                if("10000".equals(resultObj.getString("code"))){
                    log.info("免押扣款成功");
                    addArtFundingDetails(order, "1", order.getOrderAmount().toString(), order.getArtName() +":租赁订单扣款");
                    result = true;
                }
//                else {
//                    zmnClose(order); // 关闭免押订单
//                    log.info("免押扣款失败：{}", response.getBody());
//                }
            }
//            else{
//                zmnClose(order); // 关闭免押订单
//                log.info("免押扣款失败：{}", response.getBody());
//            }

            // 操作记录
            addOperationDetails(order, response.isSuccess(), "0", response.getBody());
        } catch (Exception e) {
            log.error("免押扣款失败", e);
        }
        return result;
    }

    @Override
    public boolean zmChargebacksCPAM(String compensationAmount, ArtOrder order) {
        boolean result = false;
//        ArtOrder order = artOrderMapper.selectArtOrderByParam(artOrder);

        AlipayTradePayRequest request = new AlipayTradePayRequest();
        AlipayTradePayModel model = new AlipayTradePayModel();

        // 设置商户订单号
        model.setOutTradeNo(order.getOrderNo());
//        if(order.getParentOrderNo() != null){
//            model.setOutTradeNo(order.getParentOrderNo()); // 续租订单从主订单扣款
//        }

        // 设置订单总金额
        model.setTotalAmount(compensationAmount);

        // 设置订单标题
        model.setSubject(order.getArtName() +"追缴扣款");

        // 设置资金预授权单号
        model.setAuthNo(order.getZmAuthOrderNo());

        // 设置产品码
        model.setProductCode("PREAUTH_PAY");

        request.setBizModel(model);
        try {
            AlipayClient alipayClient = aliConfigService.client();

            log.info("免押扣款请求参数:{}",request.getBizModel().toString());

            // 调用接口扣款
            AlipayTradePayResponse response = alipayClient.execute(request);

            log.info("免押扣款接口返回结果:{}",response.getBody());

            if (response.isSuccess()) {
                JSONObject resultObj = JSONObject.parseObject(response.getBody()).getJSONObject("alipay_trade_pay_response");
                if("10000".equals(resultObj.getString("code"))){
                    log.info("免押扣款成功");
                    addArtFundingDetails(order, "1", compensationAmount, order.getArtName() +":售后扣款");

                    result = true;
                }else {
                    log.info("免押扣款失败：{}", response.getBody());
                }
            }

            // 操作记录
            addOperationDetails(order, response.isSuccess(), "0", response.getBody());
        } catch (Exception e) {
            log.error("免押扣款失败", e);
            return false;
        }
        return result;
    }

    /**
     * 关闭免押订单
     * @param order
     * @return
     */
    @Override
    public boolean zmnClose(ArtOrder order) {
        try {
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();

            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", order.getOrderNo());
            request.setBizContent(bizContent.toString());


            log.info("关闭免押订单请求参数:{}",request.getBizContent().toString());

            AlipayClient alipayClient = aliConfigService.client();

            // 调用关闭免押订单
            AlipayTradeCloseResponse response = alipayClient.execute(request);

            log.info("关闭免押订单返回结果:{}",response.getBody());

            if(response.isSuccess()){
                JSONObject resultObj = JSONObject.parseObject(response.getBody()).getJSONObject("alipay_trade_close_response");
                if("10000".equals(resultObj.getString("code"))){
                    log.info("关闭免押订单成功");
                }
            }

            // 操作记录
            addOperationDetails(order, response.isSuccess(), "3", response.getBody());
            return response.isSuccess();
        }catch (Exception e) {
            log.error("关闭免押订单申请失败", e);
            return false;
        }
    }

    /**
     * 取消免押订单
     * @param order
     */
    @Override
    public boolean zmCancel(ArtOrder order) {
        try {
            // 构造请求参数以调用接口
            AlipayFundAuthOperationCancelRequest request = new AlipayFundAuthOperationCancelRequest();
            AlipayFundAuthOperationCancelModel model = new AlipayFundAuthOperationCancelModel();

            // 设置支付宝授权资金订单号
            model.setAuthNo(order.getZmAuthOrderNo());

            // 设置商户的授权资金订单号
            model.setOutOrderNo(order.getOrderNo());

            // 设置支付宝的授权资金操作流水号
//            model.setOperationId("20161012405744018102");

            // 设置商户的授权资金操作流水号
            model.setOutRequestNo(order.getOrderRequestNo());

            // 设置商户对本次撤销操作的附言描述
            model.setRemark(order.getArtName() + "取消免押");

            request.setBizModel(model);

            AlipayClient alipayClient = aliConfigService.client();

            log.info("取消免押订单请求参数:{}",request.getBizModel().toString());

            // 调用接口取消免押订单
            AlipayFundAuthOperationCancelResponse response = alipayClient.execute(request);

            log.info("取消免押订单接口返回结果:{}",response.getBody());

            if (response.isSuccess()) {
                log.info("取消免押订单成功");
            }

            // 操作记录
            addOperationDetails(order, response.isSuccess(), "2", response.getBody());
            return response.isSuccess();
        }catch (Exception e) {
            log.error("取消免押订单失败", e);
            return false;
        }
    }

    /**
     * 解冻免押资金，如果解冻全部就是完成免押订单
     * 如果需要解冻剩余的资金，先调用查询免押订单接口，获取剩余资金使用，放到artOrder的FreezeAmount中，然后调用解冻接口
     * @param order
     */
    @Override
    public boolean zmnfreeze(ArtOrder order) {
        boolean result = false;
        try {
            AlipayFundAuthOrderUnfreezeRequest request = new AlipayFundAuthOrderUnfreezeRequest();

            JSONObject bizContent = new JSONObject();

            bizContent.put("auth_no",order.getZmAuthOrderNo());

//            if(order.getOrderRequestNo() != null){
//                bizContent.put("out_request_no",order.getOrderRequestNo());
//            }else{
//                bizContent.put("out_request_no","zmjd" + DateUtils.dateTimeNow());
//            }
            bizContent.put("out_request_no","zmjd" + DateUtils.dateTimeNow());

            bizContent.put("amount",order.getUnfreezeAmount().toString()); // 解冻金额
            bizContent.put("remark",order.getArtName() + "解冻资金");

            JSONObject extraParam = new JSONObject();
            JSONObject unfreezeBizInfo = new JSONObject();
            unfreezeBizInfo.put("bizComplete",true); // 设置这个参数，表示用户已经履约
            extraParam.put("unfreezeBizInfo",unfreezeBizInfo);
            bizContent.put("extra_param",extraParam);

            // 设置整体请求参数
            request.setBizContent(bizContent.toString());

            AlipayClient alipayClient = aliConfigService.client();

            log.info("解冻资金请求参数:{}",request.getBizContent().toString());

            // 使用execute方法发起请求
            AlipayFundAuthOrderUnfreezeResponse response = alipayClient.execute(request);

            log.info("解冻资金接口返回结果:{}",response.getBody());

            if(response.isSuccess()){
                JSONObject resultObj = JSONObject.parseObject(response.getBody()).getJSONObject("alipay_fund_auth_order_unfreeze_response");
                if("10000".equals(resultObj.getString("code"))){
                    result = true;
                    log.info("解冻资金成功");
                }else {
                    log.info("解冻资金失败：{}", response.getBody());
                }
            }

            // 操作记录
            addOperationDetails(order, response.isSuccess(), "1", response.getBody());
        }catch (Exception e) {
            log.error("取消免押订单失败", e);
        }
        return result;
    }

    /**
     * 查询免押订单详情
     * @param order
     * @return
     */
    @Override
    public String zmnDetail(ArtOrder order) {
        try {
            // 构造请求参数以调用接口
            AlipayFundAuthOperationDetailQueryRequest request = new AlipayFundAuthOperationDetailQueryRequest();
            AlipayFundAuthOperationDetailQueryModel model = new AlipayFundAuthOperationDetailQueryModel();

            // 设置需要查询的授权资金操作类型
            model.setOperationType("FREEZE");

            if(order.getAliOrder() != null && order.getZmAuthOrderNo() != null){
                // 设置支付宝授权资金订单号
                model.setAuthNo(order.getZmAuthOrderNo());

                // 设置支付宝的授权资金操作流水号
                model.setOperationId(order.getAliOrder());
            }else if(order.getOrderRequestNo() != null) {
                // 设置商户的授权资金订单号
            model.setOutOrderNo(order.getOrderNo());

                // 设置商户的授权资金操作流水号
            model.setOutRequestNo(order.getOrderRequestNo());
            }

            request.setBizModel(model);

            AlipayClient alipayClient = aliConfigService.client();

            log.info("查询免押订单详情请求参数:{}",request.getBizModel().toString());

            // 调用接口查询订单详情
            AlipayFundAuthOperationDetailQueryResponse response = alipayClient.execute(request);

            log.info("查询免押订单详情接口返回结果:{}",response.getBody());

            if(response.isSuccess()){
                log.info("查询免押订单详情成功");
            }

            // 操作记录
            addOperationDetails(order, response.isSuccess(), "4", response.getBody());
            return response.getBody();
        }catch (Exception e) {
            log.error("查询免押订单失败", e);
            return null;
        }
    }

    /**
     * 退款申请
     * @param order
     * @return
     */
    @Override
    public boolean zmnRefund(ArtOrder order) {
        try {
            // 构造请求参数以调用接口
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();

            // 设置商户订单号
            model.setOutTradeNo(order.getOrderNo());

            // 设置退款金额
            model.setRefundAmount(order.getRefundAmount().toString());

            // 设置退款原因说明
            model.setRefundReason("正常退款");

            request.setBizModel(model);

            log.info("免押退款申请请求参数:{}",request.getBizModel().toString());

            AlipayClient alipayClient = aliConfigService.client();

            // 调用接口查询订单详情
            AlipayTradeRefundResponse response = alipayClient.execute(request);

            log.info("免押退款申请返回结果:{}",response.getBody());

            if(response.isSuccess()){
                log.info("免押退款申请成功");
            }

            // 操作记录
            addOperationDetails(order, response.isSuccess(), "3", response.getBody());
            return response.isSuccess();
        }catch (Exception e) {
            log.error("免押退款申请失败", e);
            return false;
        }
    }

    /**
     * 查询退款状态，如果成功把订单状态改成退款成功并完结订单，如果失败再次调用退款申请接口
     * @param order
     * @return
     */
    @Override
    public boolean zmnRefundStatus(ArtOrder order) {
        try {
            // 构造请求参数以调用接口
            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
            AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();

            // 设置商户订单号
            model.setOutTradeNo(order.getOrderNo());

            // 设置退款请求号
            model.setOutRequestNo(order.getOrderNo());

            request.setBizModel(model);

            log.info("免押退款查询请求参数:{}",request.getBizModel().toString());

            AlipayClient alipayClient = aliConfigService.client();

            // 调用接口查询订单详情
            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);

            log.info("免押退款查询返回结果:{}",response.getBody());

            if(response.isSuccess()){
                JSONObject result = JSONObject.parseObject(response.getBody()).getJSONObject("alipay_trade_fastpay_refund_query_response");
                String refundStatus = result.getString("refund_status");

                if("REFUND_SUCCESS".equals(refundStatus)){
                    return true;
                }
                log.info("免押退款查询成功");
            }

            // 操作记录
            addOperationDetails(order, response.isSuccess(), "5", response.getBody());
        }catch (Exception e) {
            log.error("免押退款查询失败", e);
        }
        return false;
    }
    private boolean refund(ArtOrder o,ArtOrderAfter afterOrder){
        if(o.getOrderType().equals("1") && o.getZmAuthOrderNo() != null){
            if (zmnRefundStatus(o)) {
                log.info("订单{}退款成功", o.getOrderNo());
                addArtFundingDetails(o, "2", afterOrder.getRefundMoney(), o.getArtName() +":租赁订单退款");
                // 退款成功，修改订单状态
                o.setOrderStatus("8");
                AjaxResult ajaxResult = completeZmOrder(o); // 完结订单
                if (ajaxResult.isError()) {
                    o.setOrderStatus("7"); // 解冻失败，状态回到 7-退款处理中
                }
                artOrderMapper.updateByOrderNo(o);    // 更新订单状态
                refundSuccessOrderAfterToFinish(afterOrder); // 退款完成后把售后状态修改为完成
            }else {

                if (afterOrder != null) {
                    o.setRefundAmount(new BigDecimal( afterOrder.getRefundMoney()));
                    // 退款失败，再次申请退款

                    return zmnRefund(o);
                }

            }
        } else if (o.getOrderType().equals("2") || o.getZmAuthOrderNo() == null) {
            //在这里判断一下是否微信支付 的退款
            String paymentMethod = o.getPaymentMethod();
            if("wx".equals(paymentMethod)){
                if(wxOrderRefundDetail(o)){//如果退款成功，修改订单状态
                    // 退款成功，修改订单状态
                    o.setOrderStatus("8");
                    artOrderMapper.updateByOrderNo(o);    // 更新订单状态
                    log.info("订单{}退款成功", o.getOrderNo());
                    addArtFundingDetails(o, "2", afterOrder.getRefundMoney(), o.getArtName() +":购买订单退款");
                    refundSuccessOrderAfterToFinish(afterOrder); // 退款完成后把售后状态修改为完成
                }else{//如果没有成功就进行退款
                    // 退款失败，再次申请退款
                    if (afterOrder != null) {
                        o.setRefundAmount(new BigDecimal(afterOrder.getRefundMoney()));
//                    o.setRefundAmount(o.getOrderAmount());
                        // 退款失败，再次申请退款
                        return wxOrderRefund(o);
                    }
                }
            }else {
                if (zlipayOrderRefundDetail(o)) {
                    // 退款成功，修改订单状态
                    o.setOrderStatus("8");
                    artOrderMapper.updateByOrderNo(o);    // 更新订单状态
                    log.info("订单{}退款成功", o.getOrderNo());
                    addArtFundingDetails(o, "2", afterOrder.getRefundMoney(), o.getArtName() +":购买订单退款");
                    refundSuccessOrderAfterToFinish(afterOrder); // 退款完成后把售后状态修改为完成
                }else {
                    // 退款失败，再次申请退款
                    if (afterOrder != null) {
                        o.setRefundAmount(new BigDecimal(afterOrder.getRefundMoney()));
//                    o.setRefundAmount(o.getOrderAmount());
                        // 退款失败，再次申请退款
                        return zlipayOrderRefund(o);
                    }

                }
            }

        }
        return false;
    }
    public void refundSuccessOrderAfterToFinish(ArtOrderAfter afterOrder){
        if(null == afterOrder){
            return;
        }
        Long id = afterOrder.getId();
        if(null == id){
            return;
        }
        //退款完成后把售后状态修改为完成
        afterOrder.setStatus(IArtAfterLogService.ORDER_STATUS_FINISH);

        artOrderAfterMapper.updateArtOrderAfter(afterOrder);
    };
    @Override
    public boolean afterZmnRefund(String orderNo) {

        ArtOrder o = artOrderMapper.getOrderByOrderNo(orderNo);
        ArtOrderAfter afterOrder = artOrderAfterMapper.getAfterOrderByOrderNo(orderNo);
        String refundMoney = afterOrder.getRefundMoney();
        if(StringUtils.isEmpty(refundMoney)){
            refundMoney = "0";
        }
        o.setRefundAmount(new BigDecimal(refundMoney));
       return refund(o,afterOrder);
    }

    /**
     * 定时任务，每10分钟执行一次，查询退款状态并处理
     */
    @Override
    public void zmnRefundTask() {
        ArtOrder order = new ArtOrder();
        order.setOrderStatus("7");
        artOrderMapper.selectArtOrderList(order).forEach(o -> {
            String orderNo = o.getOrderNo();
            ArtOrderAfter afterOrder = artOrderAfterMapper.getAfterOrderByOrderNo(orderNo);

            refund(o,afterOrder);

            /* if(o.getOrderType().equals("1")){
                if (zmnRefundStatus(o)) {
                    log.info("订单{}退款成功", o.getOrderNo());
                    addArtFundingDetails(o, "2", o.getRefundAmount().toString(), o.getArtName() +":租赁订单退款");
                    // 退款成功，修改订单状态
                    o.setOrderStatus("8");
                    AjaxResult ajaxResult = completeZmOrder(o); // 完结订单
                    if (ajaxResult.isError()) {
                        o.setOrderStatus("7"); // 解冻失败，状态回到 7-退款处理中
                    }
                    artOrderMapper.updateByOrderNo(o);    // 更新订单状态
                }else {

                    if (afterOrder != null) {
                        o.setRefundAmount(new BigDecimal( afterOrder.getRefundMoney()));
                        // 退款失败，再次申请退款
                        zmnRefund(o);
                    }

                }
            } else if (o.getOrderType().equals("2")) {
                if (zlipayOrderRefundDetail(o)) {
                    // 退款成功，修改订单状态
                    o.setOrderStatus("8");
                    artOrderMapper.updateByOrderNo(o);    // 更新订单状态
                    log.info("订单{}退款成功", o.getOrderNo());
                    addArtFundingDetails(o, "2", o.getRefundAmount().toString(), o.getArtName() +":购买订单退款");
                }else {
                    // 退款失败，再次申请退款
                    if (afterOrder != null) {
                        o.setRefundAmount(new BigDecimal( afterOrder.getRefundMoney()));
                        // 退款失败，再次申请退款
                        zlipayOrderRefund(o);
                    }

                }
            }*/
        });
    }

    @Override
    public void sendSmsTask() {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        // 必填，请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
        config.setAccessKeyId(aliyunSmsConfig.getAccessKeyId());
        // 必填，请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        config.setAccessKeySecret(aliyunSmsConfig.getAccessSecret());
        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
        config.endpoint = "dysmsapi.aliyuncs.com";
        com.aliyun.dysmsapi20170525.Client client = null;
        try {
            client = new com.aliyun.dysmsapi20170525.Client(config);
        }catch (Exception e) {
             log.error("短信客户端初始化失败",e.getMessage());
        }
                // 查询需要发送短信的订单，rental_end_date 前 5、3、1 天的记录，查询结果中把到期前几天放到了RentalDays中
        List<ArtOrder> smsOrderList = artOrderMapper.getSmsOrderList();
        for (ArtOrder order : smsOrderList) {
            // 发送短信
            String mobile = order.getDeliveryPhone();
//            String content = "您租赁的["  + order.getArtName() + "]还有" + order.getRentalDays() + "天到期，" +
//                    "到期后系统将为您自动续租一个月，如果您需要归还作品，请在[下个月4号]之前把作品邮寄回来，" +
//                    "快递信息[xxxxxx]，" +
//                    "作品邮寄后请在订单点击归还按钮填写快递单号并上传快递单照片，" +
//                    "[特别提醒]如果您在下个月的4号之前没有在小程序填写快递信息，系统将为您自动续租一个月";

            // 短信模板变量参数，name-用户昵称；art_name-其他（如名称、账号、地址等）；days-时间；address-地址
            Map<String, String> smsParams = new HashMap<>();
            smsParams.put("name", order.getDeliveryName());
            smsParams.put("art_name", order.getArtName());
            smsParams.put("days", order.getRentalDays().toString());
            smsParams.put("address", aliyunSmsConfig.getKdAddress());
            smsParams.put("tel", aliyunSmsConfig.getKdTel());

            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setPhoneNumbers(mobile)
                    .setSignName(aliyunSmsConfig.getSignName())
                    .setTemplateCode(aliyunSmsConfig.getTemplateCode())
                    .setTemplateParam(JSONObject.toJSONString(smsParams));
            try {
                // 复制代码运行请自行打印 API 的返回值
                SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, new com.aliyun.teautil.models.RuntimeOptions());
                log.info("短信发送接口返回结果:{}",response.getBody());
                if(response.getBody().getCode().equals("OK")){
                    log.info("短信发送成功", mobile, JSONObject.toJSONString(smsParams));
                }else{
                    log.error("短信发送失败", mobile, JSONObject.toJSONString(smsParams));
                }
            } catch (TeaException error) {
                // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
                // 错误 message
                log.error("短信发送异常",error.getMessage());
                // 诊断地址
                log.error("短信发送异常",(String) error.getData().get("Recommend"));
                com.aliyun.teautil.Common.assertAsString(error.message);
            } catch (Exception _error) {
                TeaException error = new TeaException(_error.getMessage(), _error);
                // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
                // 错误 message
                log.error("短信发送异常",error.getMessage());
                // 诊断地址
                log.error("短信发送异常",(String) error.getData().get("Recommend"));
                com.aliyun.teautil.Common.assertAsString(error.message);
            }
        }
    }

    /**
     * 购物车购买流程创建支付宝支付订单
     * @param userId 用户订单
     * @param tradeNo 交易号
     * @param orderAmount 订单金额
     * @param orders 原生订单数据
     * @return
     */
    private String createCartAlipayOrder(Long userId,String tradeNo,String orderAmount,CartArtOrder orders) {
        String result = null;
        try {
            //userId TradeNo OrderAmount ArtName 操作记录order
            ArtUser artUser = artUserMapper.selectArtUserById(userId);
            // 构造请求参数以调用接口
            AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
            AlipayTradeCreateModel model = new AlipayTradeCreateModel();

            // 设置异步通知
            request.setNotifyUrl(myAliPayConfig.getNotifyCartBuyUrl());

            // 设置商户订单号
            model.setOutTradeNo(tradeNo);

            // 设置产品码
            model.setProductCode("JSAPI_PAY");

            // 设置小程序支付中，小程序appId
            model.setOpAppId("2021004137664197");

            // 设置订单总金额
            model.setTotalAmount(orderAmount);

            // 设置订单标题
            model.setSubject("木丁艺术品购物车订单");

            // 设置买家支付宝用户唯一标识
            model.setBuyerOpenId(artUser.getAliOpenId());

            request.setBizModel(model);

            AlipayClient alipayClient = aliConfigService.client();

            log.info("创建支付宝支付订单请求参数:{}",request.getBizModel().toString());

            AlipayTradeCreateResponse response = alipayClient.execute(request);

            log.info("创建支付宝支付订单返回结果:{}",response.getBody());

            if(response.isSuccess()){
                result = response.getBody();
            }
            ArtOrder artOrder = new ArtOrder();
            artOrder.setUserId(userId);
            artOrder.setOrderType("2");
            artOrder.setOrderAmount(new BigDecimal(orderAmount));
            artOrder.setAliTradeNo(tradeNo);
            addOperationDetails(artOrder, response.isSuccess(), "6", response.getBody());
        }catch (Exception e) {
            log.error("创建支付宝支付订单失败", e);
        }
        return result;
    }
    /**
     * 购物车购买流程创建支付宝支付订单
     * @param userId 用户订单
     * @param tradeNo 交易号
     * @param orderAmount 订单金额
     * @param orders 原生订单数据
     * @return
     */
    private String createWXCartOrder(Long userId,String tradeNo,String orderAmount,CartArtOrder orders,String ip) {

        try {
            ArtUser artUser = artUserMapper.selectArtUserById(userId);
            String wxOpenId = artUser.getWxOpenId();
            if(StringUtils.isEmpty(wxOpenId)){
                throw new RuntimeException("用户未绑定微信");
            }
            WXPay wxPay = new WXPay(wxPayConfig);
            Map<String,Object> attach = new HashMap<>();
            attach.put("orders",tradeNo);
            attach.put("openId",wxOpenId);

            String s = tradeNo;
            //orderAmount 元转分
             int total_fee  = AmountUtils.changeY2F(new BigDecimal(orderAmount).doubleValue());
            HashMap param = new HashMap();
            param.put("nonce_str", WXPayUtil.generateNonceStr());
            param.put("body", "木丁艺术品购买订单");
            param.put("out_trade_no", s);
            //String totalFee = NumberUtil.mul(wxPayForm.getAmount().toString(), "100").setScale(0, RoundingMode.FLOOR).toString();
            param.put("total_fee", total_fee);
            param.put("spbill_create_ip", ip);
            // param.put("spbill_create_ip","47.92.208.59");
            //47.92.208.59
            //填写接收付款结果的接口
            param.put("notify_url", wxPayConfig.getNotifyCartBuyUrl());
            param.put("trade_type", "JSAPI");
            param.put("openid",wxOpenId);
            param.put("attach", JSON.toJSONString(attach));
            Map<String, String> result = wxPay.unifiedOrder(param);
            String prepayId = result.get("prepay_id");
            if (prepayId != null) {
                param.clear();
                param.put("appId", wxPayConfig.getAppID());
                String timeStamp = new Date().getTime() + "";
                param.put("timeStamp", timeStamp);
                String nonceStr = WXPayUtil.generateNonceStr();
                param.put("nonceStr", nonceStr);
                param.put("package", "prepay_id=" + prepayId);
                param.put("signType", "MD5");
                String signature = WXPayUtil.generateSignature(param, wxPayConfig.getKey());
                param.clear();
                param.put("package", "prepay_id=" + prepayId);
                param.put("timeStamp", timeStamp);
                param.put("nonceStr", nonceStr);
                param.put("paySign", signature);
                param.put("outTradeNo", s);
                param.put("total_fee", total_fee);


                ArtOrder artOrder = new ArtOrder();
                artOrder.setUserId(userId);
                artOrder.setOrderType("2");
                artOrder.setOrderAmount(new BigDecimal(orderAmount));
                artOrder.setAliTradeNo(tradeNo);
                addOperationDetails(artOrder, true, "6", JSON.toJSONString(param));
                return JSON.toJSONString(param);
            } else {
                throw new RuntimeException("创建支付订单失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("创建支付订单失败");
        }

    }
    /**
     * 创建支付宝支付订单
     * @param order
     * @return
     */
    private String createAlipayOrder(ArtOrder order) {
        String result = null;
        try {
            ArtUser artUser = artUserMapper.selectArtUserById(order.getUserId());
            // 构造请求参数以调用接口
            AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
            AlipayTradeCreateModel model = new AlipayTradeCreateModel();

            // 设置异步通知
            request.setNotifyUrl(myAliPayConfig.getNotifyBuyUrl());

            // 设置商户订单号
            model.setOutTradeNo(order.getAliTradeNo());

            // 设置产品码
            model.setProductCode("JSAPI_PAY");

            // 设置小程序支付中，小程序appId
            model.setOpAppId("2021004137664197");

            if("2".equals(order.getOrderType())){
                // 设置订单总金额
                model.setTotalAmount(order.getOrderAmount().toString());
            }else if("1".equals(order.getOrderType())){
                // 设置订单总金额
                model.setTotalAmount(order.getFreezeAmount().toString());
            }

            // 设置订单标题
            model.setSubject(order.getArtName());

            // 设置买家支付宝用户唯一标识
            model.setBuyerOpenId(artUser.getAliOpenId());

            request.setBizModel(model);

            AlipayClient alipayClient = aliConfigService.client();

            log.info("创建支付宝支付订单请求参数:{}",request.getBizModel().toString());

            AlipayTradeCreateResponse response = alipayClient.execute(request);

            log.info("创建支付宝支付订单返回结果:{}",response.getBody());

            if(response.isSuccess()){
                result = response.getBody();
            }

            addOperationDetails(order, response.isSuccess(), "6", response.getBody());
        }catch (Exception e) {
            log.error("创建支付宝支付订单失败", e);
        }
        return result;
    }
    /**
     * 创建微信支付订单
     * @param order
     * @return
     */
    private String createWxOrder(ArtOrder order) {
        try {
            //微信的接口交易金额单位是分，所以需要转换
            Long userId = order.getUserId();
            //setWechatOrder
            String tradeNo = order.getWechatOrder();
            String orderAmount = order.getOrderAmount().toString();
            String ip = order.getIp();
            ArtUser artUser = artUserMapper.selectArtUserById(userId);
            String wxOpenId = artUser.getWxOpenId();
            if(StringUtils.isEmpty(wxOpenId)){
                throw new RuntimeException("用户未绑定微信");
            }
            WXPay wxPay = new WXPay(wxPayConfig);
            Map<String,Object> attach = new HashMap<>();
            attach.put("orders",tradeNo);
            attach.put("openId",wxOpenId);
            //orderAmount 元转分
            int total_fee  = AmountUtils.changeY2F(new BigDecimal(orderAmount).doubleValue());
            String s = tradeNo;
            HashMap param = new HashMap();
            param.put("nonce_str", WXPayUtil.generateNonceStr());
            param.put("body", "木丁艺术品购买订单");
            param.put("out_trade_no", s);
            //String totalFee = NumberUtil.mul(wxPayForm.getAmount().toString(), "100").setScale(0, RoundingMode.FLOOR).toString();
            param.put("total_fee", total_fee + "");
            param.put("spbill_create_ip", ip);
            // param.put("spbill_create_ip","47.92.208.59");
            //47.92.208.59 setWechatOrder
            //填写接收付款结果的接口
            param.put("notify_url", wxPayConfig.getNotifyBuyUrl());
            param.put("trade_type", "JSAPI");
            param.put("openid",wxOpenId);
            param.put("attach", JSON.toJSONString(attach));
            Map<String, String> result = wxPay.unifiedOrder(param);
            String prepayId = result.get("prepay_id");
            if (prepayId != null) {
                param.clear();
                param.put("appId", wxPayConfig.getAppID());
                String timeStamp = new Date().getTime() + "";
                param.put("timeStamp", timeStamp);
                String nonceStr = WXPayUtil.generateNonceStr();
                param.put("nonceStr", nonceStr);
                param.put("package", "prepay_id=" + prepayId);
                param.put("signType", "MD5");
                String signature = WXPayUtil.generateSignature(param, wxPayConfig.getKey());
                param.clear();
                param.put("package", "prepay_id=" + prepayId);
                param.put("timeStamp", timeStamp);
                param.put("nonceStr", nonceStr);
                param.put("paySign", signature);
                param.put("outTradeNo", s);
                param.put("total_fee", total_fee);


                ArtOrder artOrder = new ArtOrder();
                artOrder.setUserId(userId);
                artOrder.setOrderType("2");
                artOrder.setOrderAmount(new BigDecimal(orderAmount));
                artOrder.setAliTradeNo(tradeNo);
                addOperationDetails(artOrder, true, "6", JSON.toJSONString(param));
                return JSON.toJSONString(param);
            } else {
                throw new RuntimeException("创建支付订单失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("创建支付订单失败");
        }

    }

    /**
     * 支付宝统一收单交易查询
     * @param order
     * @return
     */
    private String zlipayOrderDetail(ArtOrder order) {
        String result = null;
        try {
            // 构造请求参数以调用接口
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            AlipayTradeQueryModel model = new AlipayTradeQueryModel();

            // 设置商户订单号
            model.setOutTradeNo(order.getAliTradeNo());

            request.setBizModel(model);

            AlipayClient alipayClient = aliConfigService.client();

            log.info("支付宝统一收单交易查询请求参数:{}",request.getBizModel().toString());

            AlipayTradeQueryResponse response = alipayClient.execute(request);

            log.info("支付宝统一收单交易查询返回结果:{}",response.getBody());

            if(response.isSuccess()){
                result = response.getBody();
            }

            addOperationDetails(order, response.isSuccess(), "7", response.getBody());
        }catch (Exception e) {
            log.error("支付宝统一收单交易查询失败", e);
        }
        return result;
    }

    /**
     * 支付宝统一收单交易退款接口
     * @param order
     * @return
     */
    private boolean zlipayOrderRefund(ArtOrder order) {
        boolean result = false;
        try {
            // 构造请求参数以调用接口
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();

            // 设置商户订单号
            model.setOutTradeNo(order.getAliTradeNo());

            // 设置退款请求号
            model.setOutRequestNo(order.getOrderNo());

            // 设置退款金额
            model.setRefundAmount(order.getRefundAmount().toString());

            // 设置退款原因说明
            model.setRefundReason("正常退款");

            request.setBizModel(model);

            AlipayClient alipayClient = aliConfigService.client();

            log.info("支付宝统一收单交易退款请求参数:{}",request.getBizModel().toString());

            AlipayTradeRefundResponse response = alipayClient.execute(request);

            log.info("支付宝统一收单交易退款返回结果:{}",response.getBody());

            if(response.isSuccess()){
                JSONObject resBody = JSONObject.parseObject(response.getBody()).getJSONObject("alipay_trade_refund_response");
                if("10000".equals(resBody.getString("code"))){
                    if("Y".equals(resBody.getString("fund_change"))){
                        result = true;
                    }
                }
            }

            addOperationDetails(order, response.isSuccess(), "8", response.getBody());
        }catch (Exception e) {
            log.error("支付宝统一收单交易退款失败", e);
        }
        return result;
    }
    /**
     * 微信交易退款接口
     * @param order
     * @return
     */
    private boolean wxOrderRefund(ArtOrder order) {
        boolean result = false;
        try {
            String prefix  = "WXTK";
            String nowSrt = DateUtils.dateTimeNow();
            String out_refund_no = prefix + nowSrt;
            // 构造请求参数以调用接口
            WXPay wxPay = new WXPay(wxPayConfig);
            HashMap param = new HashMap();
            param.put("appid", wxPayConfig.getAppID()); //	微信支付分配的子商户号
            param.put("mch_id", wxPayConfig.getMchID() ); //微信退款单号
            param.put("nonce_str",WXPayUtil.generateNonceStr()); //随机字符串，不长于32位。推荐随机数生成算法


            param.put("transaction_id",order.getTransactionId()); //微信退款单号
            param.put("out_refund_no",out_refund_no); //商户退款单号
            int refund_fee = AmountUtils.changeY2F(new BigDecimal(order.getRefundAmount().toString()).doubleValue());
            int total_fee = AmountUtils.changeY2F(new BigDecimal(order.getOrderAmount().toString()).doubleValue());
            param.put("total_fee",total_fee); //订单金额
            param.put("refund_fee",refund_fee); //申请退款金额
            String signature = WXPayUtil.generateSignature(param, wxPayConfig.getKey());
            param.put("sign",signature);
            Map<String, String> map = wxPay.refund(param);
            String return_code = map.get("return_code");
            String refund_id = map.get("refund_id");

            log.info("微信交易退款请求参数:{}",JSONObject.toJSONString(param));
            log.info("微信交易退款返回结果:{}",JSONObject.toJSONString(map));

            if(null != return_code && "SUCCESS".toLowerCase(Locale.ROOT).equals(return_code.toLowerCase(Locale.ROOT))){
                result = true;
                ArtOrder artOrder = new ArtOrder();
                artOrder.setOrderNo(order.getOrderNo());
                artOrder.setWxRefundId(refund_id);
                artOrderMapper.updateByOrderNo(order);    // 更新订单状态
            }
            addOperationDetails(order, result, "8",JSONObject.toJSONString(map));
        }catch (Exception e) {
            log.error("支付宝统一收单交易退款失败", e);
        }
        return result;
    }
    /**
     * 支付宝统一收单交易退款查询
     * @param order
     * @return
     */
    private boolean zlipayOrderRefundDetail(ArtOrder order) {
        boolean result = false;
        try {
            // 构造请求参数以调用接口
            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
            AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();

            // 设置商户订单号
            model.setOutTradeNo(order.getAliTradeNo());

            // 设置退款请求号
            model.setOutRequestNo(order.getOrderNo());

            request.setBizModel(model);

            AlipayClient alipayClient = aliConfigService.client();

            log.info("支付宝统一收单交易退款查询请求参数:{}",request.getBizModel().toString());

            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);

            log.info("支付宝统一收单交易退款查询返回结果:{}",response.getBody());

            if(response.isSuccess()){
                JSONObject resBody = JSONObject.parseObject(response.getBody()).getJSONObject("alipay_trade_fastpay_refund_query_response");
                if("10000".equals(resBody.getString("code"))){
                    if(resBody.get("refund_status") != null && "REFUND_SUCCESS".equals(resBody.getString("refund_status"))){
                        result = true;
                    }
                }
            }

            addOperationDetails(order, response.isSuccess(), "9", response.getBody());
        }catch (Exception e) {
            log.error("支付宝统一收单交易退款查询失败", e);
        }
        return result;
    }
    /**
     * 微信统一收单交易退款查询
     * @param order
     * @return
     */
    private boolean wxOrderRefundDetail(ArtOrder order) {
        boolean result = false;
        String wxRefundId = order.getWxRefundId();
        if(StringUtils.isEmpty(wxRefundId)){
            log.info("微信交易退款查询失败，没有退款单号:{}",order.getOrderNo());
            return result;
        }
        try {
            // 构造请求参数以调用接口
            WXPay wxPay = new WXPay(wxPayConfig);
            HashMap param = new HashMap();
            param.put("appid", wxPayConfig.getAppID()); //	微信支付分配的子商户号
            param.put("mch_id", wxPayConfig.getMchID() ); //微信退款单号
            param.put("nonce_str",WXPayUtil.generateNonceStr()); //随机字符串，不长于32位。推荐随机数生成算法
            param.put("refund_id",wxRefundId); //微信退款单号
            String signature = WXPayUtil.generateSignature(param, wxPayConfig.getKey());
            param.put("sign",signature);
            Map<String, String> map = wxPay.refundQuery(param);

            log.info("微信交易退款查询请求参数:{}",JSONObject.toJSONString(param));
            log.info("微信交易退款查询返回结果:{}",JSONObject.toJSONString(map));
            String return_code = map.get("return_code");//业务状态
            String refund_status_$n = map.get("refund_status_$n");//退款状态退款状态：SUCCESS—退款成功REFUNDCLOSE—退款关闭，指商户发起退款失败的情况PROCESSING—退款处理中
            //退款状态：NOTPAY—未支付，需要用户手动输入密码支付REFUNDING—退款中，退款发给商户处理中SUCCESS—退款成功CHANGE—转入退款退货中REFUND_CHANGE—退款异常，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往商户平台（pay.weixin.qq.com）-交易中心，手动处理此笔退款。$n为下标，从0开始编号。
            if(null != return_code && "SUCCESS".toLowerCase(Locale.ROOT).equals(return_code.toLowerCase(Locale.ROOT))){
                if(null != refund_status_$n && "SUCCESS".toLowerCase(Locale.ROOT).equals(refund_status_$n.toLowerCase(Locale.ROOT))){
                    result = true;
                }
            }
            addOperationDetails(order, result, "9", JSONObject.toJSONString(map));
        }catch (Exception e) {
            log.error("微信交易退款查询失败", e);
        }
        return result;
    }
    /**
     * 操作日志
     * @param order
     * @param operationFlag 对方接口返回状态，true成功，false失败
     * @param operationType 操作类型，0-租赁扣款 1-租赁完结 2-取消免押 3-免押退款申请 4-查询免押订单详情 5-退款查询 6-创建支付宝交易订单 7-支付宝交易订单查询 8-支付宝交易订单退款 9-支付宝交易订单退款查询
     * @param operationMessage 对方接口返回信息
     */
    private void addOperationDetails(ArtOrder order, boolean operationFlag, String operationType, String operationMessage) {
        ArtOperationDetails artOperationDetails = new ArtOperationDetails();
        artOperationDetails.setOrderNo(order.getOrderNo()); // 订单编号
        artOperationDetails.setAuthNo(order.getZmAuthOrderNo()); // 授权编号
        artOperationDetails.setOrderType(order.getOrderType()); // 订单类型，1租赁2购买
        artOperationDetails.setType(operationType); // 操作类型，0租赁扣款1租赁完结2取消免押3免押退款申请4查询免押订单详情5退款查询6创建支付宝交易订单
        artOperationDetails.setStatus(operationFlag ? "0" : "1"); // 状态，0失败1成功
        artOperationDetails.setAmount(order.getOrderAmount()); // 金额
        artOperationDetails.setUserId(order.getUserId());  //用户ID
        artOperationDetails.setReqDate(new Date()); // 请求开始日期
        artOperationDetails.setResMessage(operationMessage); // 响应信息
        artOperationDetails.setTradeNo(order.getAliTradeNo());
        // 操作记录
        artOperationDetailsMapper.insert(artOperationDetails);
    }

    /**
     * 加库存，目前只加1
     * @param order
     * @return
     */
    private int addGoodsNum(ArtOrder order) {
        ArtRental artRental = new ArtRental();
        artRental.setId(order.getArtRentalId());
        artRental.setGoodsNum(1); // 收回库存
        return artRentalMapper.updateArtRental(artRental);
    }

    /**
     * 减库存，目前只减1
     * @param order
     * @return
     */
    private int subtractGoodsNum(ArtOrder order) {
        ArtRental artRental = new ArtRental();
        artRental.setId(order.getArtRentalId());
        artRental.setGoodsNum(0); // 收回库存
        return artRentalMapper.updateArtRental(artRental);
    }

    /**
     * 续租校验
     * @param order，数据库查询出来的主订单完整数据
     * @param artRental，数据库查询出来的租赁商品完整数据
     * @param currentRentalDays，当前续租的租期
     * @param auto，是否是自动续租
     */
    private String checkLeaseRenewalZmOrder(ArtOrder order, ArtRental artRental, Integer currentRentalDays, boolean auto) {
        ArtOrder artOrder = new ArtOrder();
        if(order.getParentOrderNo() != null){
            artOrder.setOrderNo(order.getParentOrderNo());
        }else{
            artOrder.setOrderNo(order.getOrderNo());
        }

        // 查询子订单
        List<ArtOrder> artOrders = artOrderMapper.getcheckLeaseRenewalZmOrder(artOrder);
        Integer totalRentalDays = order.getRentalDays();

        // 计算之前总租期
        for (ArtOrder o : artOrders) {
            if(o.getOrderStatus().equals("1") || o.getOrderStatus().equals("88")){
                totalRentalDays += o.getRentalDays();
            }
        }

        // 计算之前总租金
        BigDecimal totalRentalFee = artRental.getRentalFee().multiply(new BigDecimal(totalRentalDays));

        // 计算租金与售价的百分数
        BigDecimal percentage = totalRentalFee.divide(artRental.getPrice(), 4, BigDecimal.ROUND_HALF_UP)
                .multiply(new BigDecimal("100"));

        // 如果之前累积的总租金大于等于售价的80%，提示买断
        if(percentage.compareTo(new BigDecimal("80")) > 0){
            if(auto){ // 自动续租，如果之前累积的总租金大于等于售价的80%，直接买断
                return "maiduan";
            }
            // 提示买断
            return "您已累积的租金已超过80%，建议选择买断该商品";
        }

        // 如果还要续租的租金大于售价，提示租期过长或者买断
        if(artRental.getRentalFee().multiply(new BigDecimal(totalRentalDays + currentRentalDays)).compareTo(artRental.getPrice()) > 0){
            if(auto){ // 自动续租，如果还要续租的租金大于售价，直接买断
                return "maiduan";
            }

            if(currentRentalDays > 1){
                // 提示租期过长，请重新选择租期
                return "续租的租期过长，请重新选择租期";
            }else {
                // 提示租期不足1个月，建议买断
                return "续租的租期不足1个月，建议选择买断该商品";
            }
        }

        return "success";
    }

    /**
     * 计算续租的租期
     * @return
     */
    private Date[] calculateDate(ArtOrder mainOrder, Integer rentalDays){
        // 查询主订单下最新订单
        ArtOrder artOrder = new ArtOrder();
        artOrder.setParentOrderNo(mainOrder.getOrderNo());
        artOrder.setOrderType("1");

        // 查询子订单，根据ID倒序
        List<ArtOrder> artOrders = artOrderMapper.selectArtOrderSortById(artOrder);

        Date tmpDate = null;
        if(artOrders != null && artOrders.size() > 0){
            tmpDate = artOrders.get(0).getRentalEndDate();
        }else{
            tmpDate = mainOrder.getRentalEndDate();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(tmpDate);

//        calendar.add(Calendar.DAY_OF_YEAR, 1);
        Date rentalStartDate = calendar.getTime();

        calendar.add(Calendar.MONTH, rentalDays);
        Date rentalEndDate = calendar.getTime();

        return new Date[]{rentalStartDate, rentalEndDate};
    }

    /**
     * 添加资金明细
     * @param artOrder
     * @param fundingType 1收入（扣款）2支出（退款）
     * @param fundingAmount 金额
     * @param fundingRemark 备注
     * @return
     */
    private boolean addArtFundingDetails(ArtOrder artOrder, String fundingType, String fundingAmount, String fundingRemark) {
        ArtFundingDetails artFundingDetails = new ArtFundingDetails();
        artFundingDetails.setOrderNo(artOrder.getOrderNo());
        artFundingDetails.setFundingAmount(new BigDecimal(fundingAmount));
        artFundingDetails.setFundingDate(new Date());
        artFundingDetails.setFundingType(fundingType);//1收入2支出
        artFundingDetails.setFundingRemark(fundingRemark);
        artFundingDetails.setArtRentalId(artOrder.getArtRentalId());
        artFundingDetails.setUserId(artOrder.getUserId().toString());
        artFundingDetails.setArtName(artOrder.getArtName());
        int result = artFundingDetailsMapper.insert(artFundingDetails);

        if(result > 0){
            log.info("添加资金明细成功:{}", artFundingDetails.toString());
            return true;
        }

        return false;
    }

    /**
     * 追缴订单创建支付宝trade_no
     * @param artOrder
     * @return
     */
    @Override
    public String getRecoveryOrderTradeNo(ArtOrder artOrder) {
        ArtOrder tmp = artOrderMapper.selectArtOrderByParam(artOrder);
        // 创建支付宝支付订单
        String result = createAlipayOrder(tmp);

        if(result != null && !"".equals(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result).getJSONObject("alipay_trade_create_response");

            if(jsonObject.getString("code").equals("10000")) {
                return jsonObject.getString("trade_no");
            }
        }

        return "fail";
    }

    /**
     * 解冻追缴成功的免押订单金额
     */
    @Override
    public void unfreezeRecoveryOrderTask() {
        ArtOrder artOrder = new ArtOrder();
        List<ArtOrder> artOrders = artOrderMapper.getUnfreezeRecoveryOrderList(artOrder);
        for(ArtOrder o : artOrders) {
            o.setUnfreezeAmount(o.getOrderAmount()); // 追缴成功，解冻金额等于支付金额
            // 解冻金额
            boolean flag = zmnfreeze(o);
            if(flag) {
                log.info("定时任务unfreezeRecoveryOrderTask：订单追缴成功，解冻金额成功，订单号：{}", o.getOrderNo());
                if("2".equals(o.getOrderType())){
                    AjaxResult ajaxResult = completeZmOrder(o);
                    if(ajaxResult.isSuccess()){
                        log.info("定时任务unfreezeRecoveryOrderTask：订单追缴成功，买断订单解冻剩余金额成功，订单号：{}", o.getOrderNo());
                    }
                }
            }
        }
    }

    /**
     * 之前的自动续租任务，现在不用了，备份保留
     */
    public void autoLeaseRenewalTask_bak(){
        // 查询所有已支付的租赁主订单
        ArtOrder orderParam = new ArtOrder();
        // 查询已支付，没有售后，租赁
        //List<ArtOrder> mainOrderList = artOrderMapper.selectMainOrderList(orderParam);
        List<ArtOrder> mainOrderList = artOrderMapper.getExpireLeaseOrder(orderParam);

        // 每天0点执行一次续租任务，自动续租租期到期时间大于当前日期3天的租赁订单，如果租期到期时间和当天差值大于6天，把此订单转为需要手动支付的订单
        for(ArtOrder mainOrder : mainOrderList) {
            // 计算两个日期之间的毫秒差
            long diffInMillies = Math.abs(new Date().getTime() - mainOrder.getRentalEndDate().getTime());

            // 将毫秒差转换为天数差
            long diffInDays = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
            // 超期6天，并且不是追缴订单的，设置为需要手动支付的订单
            if(diffInDays > 6 && mainOrder.getParentOrderNo() != null){
                mainOrder.setOrderStatus("88"); // 订单状态 88-需要手动支付
                mainOrder.setRecoveryStatus("1"); // 1-追缴未支付
                mainOrder.setAliTradeNo(mainOrder.getOrderNo()); // 设置创建支付宝订单的交易号
                mainOrder.setRecoveryReason("该订单租期逾期，请及时支付"); // 追缴原因
                artOrderMapper.updateByOrderNo(mainOrder);
            }

            autoLeaseRenewal(mainOrder);
        }
    }

    /**
     * 租赁订单续租，自动续租
     * @param order
     * @return
     */
    public AjaxResult autoLeaseRenewal(ArtOrder order) {
        // 查询当前续租订单的完整数据
        ArtOrder mainOrder = artOrderMapper.getOrderByOrderNo(order.getOrderNo());

        Integer currentRentalDays = mainOrder.getRentalDays(); // 自动续租天数，自动，延续上一个订单的续租天数

        ArtRental artRental = artRentalMapper.selectArtRentalById(mainOrder.getArtRentalId());

        Date[] dateArr = calculateDate(mainOrder, currentRentalDays);
        Date rentalStartDate = dateArr[0];
        Date rentalEndDate = dateArr[1];

        String result = checkLeaseRenewalZmOrder(mainOrder, artRental, currentRentalDays, true);

        log.info("自动续租校验结果{}：{}", mainOrder.getOrderNo(), result);

        // 组装续租订单数据
        ArtOrder renewalOrder = new ArtOrder();
        renewalOrder.setOrderNo(ORDER_PREFIX + DateUtils.dateTimeNow());
        renewalOrder.setOrderRequestNo(renewalOrder.getOrderNo());
        renewalOrder.setZmAuthOrderNo(mainOrder.getZmAuthOrderNo()); // 支付宝授权资金订单号
        renewalOrder.setAliOrder(mainOrder.getAliOrder()); // 支付宝的授权资金操作流水号

        if(mainOrder.getParentOrderNo() != null){
            renewalOrder.setParentOrderNo(mainOrder.getParentOrderNo());
        }else{
            renewalOrder.setParentOrderNo(mainOrder.getOrderNo());
        }

        renewalOrder.setOrderStatus("0"); // 订单状态，0待支付
        renewalOrder.setArtRentalId(mainOrder.getArtRentalId()); // 商品ID
        renewalOrder.setArtName(mainOrder.getArtName()); // 商品名称
        renewalOrder.setCreateTime(new Date());
        renewalOrder.setUpdateTime(new Date());
        renewalOrder.setUserId(mainOrder.getUserId());

        if("success".equals(result)){ // 续租
            // 组装续租订单数据
            renewalOrder.setOrderType("1"); // 订单类型，1租赁
            renewalOrder.setRentalDays(currentRentalDays); // 续租的租期
            renewalOrder.setRentalStatus("0"); // 租赁状态，0-待确认
            renewalOrder.setOrderAmount(artRental.getRentalFee().multiply(new BigDecimal(currentRentalDays))); // 续租的租金
            renewalOrder.setRentalStartDate(rentalStartDate); // 续租的开始日期
            renewalOrder.setRentalEndDate(rentalEndDate); // 续租的结束日期

            // 扣款逻辑，只记录当期续租的数据不扣款，对上一期的续租订单进行扣款
            // 查询上一期的续租订单，如果存在，则扣款，因为当期续租订单还没有插入数据库，所以上一期就是续租订单的最后一个
            ArtOrder preRenewalOrder = null;
            // 如果mainOrder的父订单号不为空，说明是续租订单，也就是上一期的续租订单
            if(mainOrder.getParentOrderNo() != null){
                preRenewalOrder = mainOrder;
            }

            boolean zmChargebacksFlag = true;

            // 如果上一期的续租订单存在，并且状态不是需要手动支付的，并且支付宝交易号为空（不为空时是88追缴订单已支付），则扣款
            if(preRenewalOrder != null
                    && !preRenewalOrder.getOrderStatus().equals("88")
                    && preRenewalOrder.getAliTradeNo() == null) {
                zmChargebacksFlag = zmChargebacks(preRenewalOrder); // 冻结资金部分扣款

                log.info("自动续租扣款{}：{}", (zmChargebacksFlag ? "成功" : "失败"), renewalOrder.getOrderNo());
                if(!zmChargebacksFlag) {
                    preRenewalOrder.setOrderStatus("88"); // 订单状态 88-需要手动支付
                    preRenewalOrder.setRecoveryStatus("1"); // 1-追缴未支付
                    preRenewalOrder.setAliTradeNo(renewalOrder.getOrderNo()); // 设置创建支付宝订单的交易号
                    preRenewalOrder.setRecoveryReason("该订单自动续租扣款失败，请及时支付"); // 追缴原因
                    artOrderMapper.updateByOrderNo(preRenewalOrder);
                }
            }

            if(zmChargebacksFlag) {
                renewalOrder.setRentalStatus("1"); // 租赁状态 1-租赁中
                renewalOrder.setOrderStatus("1"); // 订单状态 1-已支付
            }

            ArtMessage artMessage = new ArtMessage();
            artMessage.setTitle("订单自动续租提醒");
            artMessage.setContent("您的租赁订单" + mainOrder.getOrderNo() + "已过期3天且并未申请归还，系统已自动续租，续租单号：" + renewalOrder.getOrderNo());
            artMessage.setStatus("0");
            artMessage.setType("0");
            artMessage.setSender(0l); // 0表示系统发送
            artMessage.setReceiver(renewalOrder.getUserId());
            artMessage.setSendTime(new Date());
            artMessageMapper.insertArtMessage(artMessage);

            artOrderMapper.insertArtOrder(renewalOrder); // 记录当期续租订单

        } else if ("maiduan".equals(result)) { // 买断
            String zmOrderString = zmnDetail(mainOrder);
            JSONObject zmOrder = JSONObject.parseObject(zmOrderString).getJSONObject("alipay_fund_auth_operation_detail_query_response");
            if(zmOrder.getString("code").equals("10000")) {
                // 订单当前剩余冻结金额，单位为：元
                String restAmount = zmOrder.getString("rest_amount");
                // 组装续租订单数据
                renewalOrder.setOrderType("2"); // 订单类型，2购买
                renewalOrder.setOrderAmount(new BigDecimal(restAmount)); // 剩余的冻结金额作为商品售价

                boolean zmChargebacksFlag =  zmChargebacks(renewalOrder); // 冻结资金部分扣款

                if(zmChargebacksFlag) {
                    renewalOrder.setOrderStatus("6"); // 订单状态 1-已支付

                    mainOrder.setOrderStatus("6"); // 订单状态 6-完成
                    artOrderMapper.updateByOrderNo(mainOrder); // 更新主订单状态

                }else { // 买断免押扣款失败，订单转为需要手动支付的订单
                    renewalOrder.setOrderStatus("88"); // 订单状态 88-需要手动支付
                    renewalOrder.setRecoveryStatus("1"); // 1-追缴未支付
                    renewalOrder.setAliTradeNo(renewalOrder.getOrderNo()); // 设置创建支付宝订单的交易号
                    renewalOrder.setRecoveryReason("该订单自动买断扣款失败，请及时支付"); // 追缴原因
                }

                log.info("自动续租买断{}：{}", (zmChargebacksFlag ? "成功" : "失败"), renewalOrder.getOrderNo());

                ArtMessage artMessage = new ArtMessage();
                artMessage.setTitle("订单自动续租提醒");
                artMessage.setContent("您的租赁订单" + mainOrder.getOrderNo() + "已过期3天且并未申请归还，再次续租的租金已经大于剩余的冻结金额，系统已自动买断，买断单号：" + renewalOrder.getOrderNo());
                artMessage.setStatus("0");
                artMessage.setType("0");
                artMessage.setSender(0l); // 0表示系统发送
                artMessage.setReceiver(renewalOrder.getUserId());
                artMessage.setSendTime(new Date());
                artMessageMapper.insertArtMessage(artMessage);

                artOrderMapper.insertArtOrder(renewalOrder);
            }else {
                log.info("查询免押订单失败：{}", zmOrder);
            }
        }

        return AjaxResult.success(result);
    }
}
